This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
[gcjx] Patch: FYI: new helper classes
- From: Tom Tromey <tromey at redhat dot com>
- To: Java Patch List <java-patches at gcc dot gnu dot org>
- Date: 29 Jan 2005 19:26:28 -0700
- Subject: [gcjx] Patch: FYI: new helper classes
- Reply-to: tromey at redhat dot com
I'm checking this in on the gcjx branch.
This adds some new 'aot' classes that help with ahead-of-time
compilers. This is a bit more generic than really needed, since I
want to make it simpler to try out LLVM at some future date. So,
vtable layout, [oai]table management, name mangling, and a few other
things like that can be handled generically. That way either a gcc or
llvm back end can share some code. Probably a few bits from the CNI
header generator will migrate here as well.
This code compiles but hasn't been tested. I haven't yet hooked it up
to the code in gcc/java.
Tom
Index: ChangeLog
from Tom Tromey <tromey@redhat.com>
* aot/mangle.cc: New file.
* aot/mangle.hh: New file.
* aot/aotfactory.cc: New file.
* aot/aotfactory.hh: New file.
* aot/aotclass.cc: New file.
* aot/aotclass.hh: New file.
* Makefile.in: Rebuilt.
* Makefile.am (aot_sources): New macro.
(libgcjx_la_SOURCES): Use it.
Index: Makefile.am
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/Attic/Makefile.am,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 Makefile.am
--- Makefile.am 23 Jan 2005 23:07:16 -0000 1.1.2.2
+++ Makefile.am 30 Jan 2005 02:21:07 -0000
@@ -12,7 +12,8 @@
libgcjx_la_SOURCES = $(dot_sources) $(model_sources) $(reader_sources) \
$(source_sources) $(format_sources) $(bytecode_sources) \
-$(header_sources) $(fdlibm_c_sources) $(fdlibm_cc_sources)
+$(header_sources) $(fdlibm_c_sources) $(fdlibm_cc_sources) \
+$(aot_sources)
BUILT_SOURCES = source/keyword.h source/chartables.h typedefs.hh.gch
@@ -130,3 +131,5 @@
fdlibm/w_sqrt.c
fdlibm_cc_sources = fdlibm/classpath.cc
+
+aot_sources = aot/aotclass.cc aot/aotfactory.cc aot/mangle.cc
Index: PROJECTS
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/Attic/PROJECTS,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 PROJECTS
--- PROJECTS 26 Jan 2005 01:26:04 -0000 1.1.2.2
+++ PROJECTS 30 Jan 2005 02:21:08 -0000
@@ -240,6 +240,9 @@
global.hh
visitor.hh
+code for helping ahead-of-time compilers:
+ everything in aot/
+
if we write threading code, put in thread/; see bkoz's libthread++
and also thread-local extension class.
Index: TODO
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/Attic/TODO,v
retrieving revision 1.1.2.11
diff -u -r1.1.2.11 TODO
--- TODO 26 Jan 2005 01:26:04 -0000 1.1.2.11
+++ TODO 30 Jan 2005 02:21:08 -0000
@@ -1,6 +1,9 @@
gcjx also fails on PR 19629, though differently
it creates the anonymous constructor incorrectly
+right now we use mmap() for reading files
+we should optionally use read() or fread()
+
in a few places in the bytecode back end we
add_utf(...->get_descriptor()). this fails if the class is a member
instead we need a new method on the constant pool
@@ -677,3 +680,5 @@
18789
18796
19070
+
+19674
Index: aot/aotclass.cc
===================================================================
RCS file: aot/aotclass.cc
diff -N aot/aotclass.cc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ aot/aotclass.cc 30 Jan 2005 02:21:08 -0000
@@ -0,0 +1,236 @@
+// Per-class wrapper for AOT compilers.
+
+// Copyright (C) 2005 Free Software Foundation, Inc.
+//
+// This file is part of GCC.
+//
+// GCC is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2, or (at your option)
+// any later version.
+//
+// GCC 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
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+
+#include "typedefs.hh"
+#include "aot/aotclass.hh"
+#include "aot/aotfactory.hh"
+
+aot_class::aot_class (aot_class_factory *cf, model_class *k)
+ : factory (cf),
+ klass (k),
+ vtable_done (false)
+{
+}
+
+void
+aot_class::lay_out_vtable ()
+{
+ if (vtable_done)
+ return;
+ vtable_done = true;
+
+ model_class *sk = klass->get_superclass ();
+ aot_class *super = sk ? factory->get_class (sk) : NULL;
+
+ vtable = super->vtable;
+
+ for (AllMethodsIterator i = klass->begin_all_methods ();
+ i != klass->end_all_methods ();
+ ++i)
+ {
+ if ((*i)->static_p ())
+ continue;
+
+ model_class *declaring_class = (*i)->get_declaring_class ();
+ if (declaring_class->interface_p ())
+ {
+ // If this interface is implemented by some superclass, then
+ // it will already appear in the vtable and we need do
+ // nothing.
+ if (super && declaring_class->assignable_from_p (super->klass))
+ continue;
+ }
+ else if (declaring_class != klass)
+ {
+ // The method was declared in some concrete superclass, so
+ // is already processed.
+ continue;
+ }
+ else if (super)
+ {
+ // See if this method overrides some method in the
+ // superclass.
+ unsigned int index = 0;
+ std::string name = (*i)->get_name ();
+ for (std::vector<model_method *>::const_iterator j
+ = super->vtable.begin ();
+ j != super->vtable.end ();
+ ++j, ++index)
+ {
+ // Note that hides_or_overrides_p does not check the
+ // method name. FIXME?
+ if (name == (*j)->get_name ()
+ && (*i)->hides_or_overrides_p (*j, klass))
+ {
+ // Re-use the previous slot.
+ vtable[index] = (*i).get ();
+ break;
+ }
+ }
+ if (index != super->vtable.size ())
+ continue;
+ }
+
+ vtable.push_back ((*i).get ());
+ }
+}
+
+int
+aot_class::add_item (const pool_entry &entry)
+{
+ int index = 0;
+ for (std::vector<pool_entry>::const_iterator i = pool.begin ();
+ i != pool.end ();
+ ++i, ++index)
+ {
+ const pool_entry &it (*i);
+ if (entry.tag == it.tag && entry.value == it.value)
+ return index;
+ }
+
+ pool.push_back (entry);
+ return pool.size () - 1;
+}
+
+int
+aot_class::add (const std::string &s)
+{
+ pool_entry e;
+ e.tag = CONSTANT_String;
+ e.value = s;
+ return add_item (e);
+}
+
+int
+aot_class::add (model_class *k)
+{
+ pool_entry e;
+ e.tag = CONSTANT_Class;
+ e.value = k->get_descriptor ();
+ return add_item (e);
+}
+
+int
+aot_class::add_utf (const std::string &s)
+{
+ pool_entry e;
+ e.tag = CONSTANT_Utf8;
+ e.value = s;
+ return add_item (e);
+}
+
+void
+aot_class::add_type_assertion (model_class *base,
+ model_class *derived)
+{
+ // There's no need to do any assertion checking on array types.
+ // They are completely understood at compile time.
+ if (base->array_p () || derived->array_p ())
+ return;
+
+ type_assertion_entry e;
+ e.key = JV_ASSERT_TYPES_COMPATIBLE;
+ e.base = base;
+ e.derived = derived;
+ // FIXME: make sure there isn't a duplicate assertion.
+ type_assertions.push_back (e);
+}
+
+void
+aot_class::note_new (model_class *k)
+{
+ if (new_set.find (k) == new_set.end ())
+ {
+ type_assertion_entry e;
+ e.key = JV_ASSERT_IS_INSTANTIABLE;
+ e.base = k;
+ e.derived = NULL;
+ type_assertions.push_back (e);
+
+ new_set.insert (k);
+ }
+}
+
+int
+aot_class::find_in_vtable (model_method *method)
+{
+ lay_out_vtable ();
+
+ int index = 0;
+ for (std::vector<model_method *>::const_iterator i = vtable.begin ();
+ i != vtable.end ();
+ ++i, ++index)
+ {
+ if (*i == method)
+ // Note: we have two extra vtable slots; one for the class
+ // pointer and one for the GC descriptor. We tell our caller
+ // about the real offset, including these two.
+ return index + 2;
+ }
+ abort ();
+}
+
+bool
+aot_class::finalizeable_p ()
+{
+ for (model_class *t = klass; t; t = t->get_superclass ())
+ {
+ if (t->has_method_with_descriptor_p ("finalize", "()V"))
+ return true;
+ }
+ return false;
+}
+
+int
+aot_class::register_something (std::vector<model_element *> &the_map,
+ model_element *item)
+{
+ int index = 0;
+ for (std::vector<model_element *>::const_iterator i = the_map.begin ();
+ i != the_map.end ();
+ ++i, ++index)
+ {
+ if (*i == item)
+ return index;
+ }
+ index = the_map.size ();
+ the_map.push_back (item);
+ return index;
+}
+
+int
+aot_class::register_indirect_call (model_method *m)
+{
+ return register_something (m->static_p () ? atable_map : otable_map, m);
+}
+
+int
+aot_class::register_interface_call (model_method *m)
+{
+ assert (m->get_declaring_class ()->interface_p ());
+ return register_something (itable_map, m);
+}
+
+int
+aot_class::register_field_reference (model_field *f)
+{
+ return register_something (f->static_p () ? atable_map : otable_map, f);
+}
Index: aot/aotclass.hh
===================================================================
RCS file: aot/aotclass.hh
diff -N aot/aotclass.hh
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ aot/aotclass.hh 30 Jan 2005 02:21:09 -0000
@@ -0,0 +1,161 @@
+// Per-class wrapper for AOT compilers.
+
+// Copyright (C) 2005 Free Software Foundation, Inc.
+//
+// This file is part of GCC.
+//
+// GCC is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2, or (at your option)
+// any later version.
+//
+// GCC 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
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+
+#ifndef GCJX_AOT_AOTCLASS_HH
+#define GCJX_AOT_AOTCLASS_HH
+
+class aot_class_factory;
+
+/// These must be kept in sync with libgcj.
+typedef enum
+{
+ JV_ASSERT_END_OF_TABLE = 0,
+ JV_ASSERT_TYPES_COMPATIBLE = 1,
+ JV_ASSERT_IS_INSTANTIABLE = 2
+} type_assertion_type;
+
+/// This class is used to keep track of per-class data for an AOT
+/// compiler.
+class aot_class
+{
+ /// This represents one entry in the constant pool.
+ struct pool_entry
+ {
+ /// Type tag.
+ classfile_type_constant tag;
+ /// String value or class name.
+ std::string value;
+ };
+
+ /// This is used in type assertions.
+ struct type_assertion_entry
+ {
+ type_assertion_type key;
+ model_class *base;
+ model_class *derived;
+ };
+
+ /// The class factory. FIXME: require it as a parameter and not
+ /// keep it as state?
+ aot_class_factory *factory;
+
+ /// The class we wrap.
+ model_class *klass;
+
+ /// The constant pool.
+ std::vector<pool_entry> pool;
+
+ /// The vtable.
+ std::vector<model_method *> vtable;
+ /// True if vtable laid out.
+ bool vtable_done;
+
+ /// Type assertions.
+ std::vector<type_assertion_entry> type_assertions;
+
+ /// All the classes we registered as needing 'new'.
+ std::set<model_class *> new_set;
+
+ /// The otable, atable, and itable.
+ std::vector<model_element *> otable_map;
+ std::vector<model_element *> atable_map;
+ std::vector<model_element *> itable_map;
+
+
+ // Compute the vtable.
+ void lay_out_vtable ();
+
+ // Add an item to the constant pool.
+ int add_item (const pool_entry &);
+
+ // Helper for putting things into one of the tables.
+ int register_something (std::vector<model_element *> &, model_element *);
+
+public:
+
+ aot_class (aot_class_factory *, model_class *);
+
+ /// Add a string to the constant pool. Returns the index of the
+ /// item.
+ int add (const std::string &);
+
+ /// Add a Utf8Const to the constant pool. Returns the index of this
+ /// item.
+ int add_utf (const std::string &);
+
+ /// Add a class reference to the constant pool. Returns the index
+ /// of the item.
+ int add (model_class *);
+
+ /// Add an assertion that BASE is a superclass or superinterface of
+ /// DERIVED.
+ void add_type_assertion (model_class *base, model_class *derived);
+
+ /// Call this to indicate a class must be instantiable at runtime.
+ void note_new (model_class *);
+
+ /// Register a method that is called from the body of this class.
+ /// The method is added to the atable (if static) or otable (if not
+ /// static). Returns the index into the table.
+ int register_indirect_call (model_method *);
+
+ /// Register an interface method that is called from the body of
+ /// this class. The method is added to the itable. Returns the
+ /// index into the table.
+ int register_interface_call (model_method *);
+
+ /// Register a field reference that is made from the body of this
+ /// class. The field is added to the atable or otable as
+ /// appropriate. Returns the index into the table.
+ int register_field_reference (model_field *);
+
+ /// Find index of a method in the vtable.
+ int find_in_vtable (model_method *);
+
+ /// See whether this class has a finalizer. This is useful if the
+ /// AOT compiler wants to call different allocators depending on
+ /// finalizability.
+ bool finalizeable_p ();
+
+ /// Return the vtable.
+ const std::vector<model_method *> &get_vtable ()
+ {
+ lay_out_vtable ();
+ return vtable;
+ }
+
+ const std::vector<model_element *> &get_otable () const
+ {
+ return otable_map;
+ }
+
+ const std::vector<model_element *> &get_atable () const
+ {
+ return atable_map;
+ }
+
+ const std::vector<model_element *> &get_itable () const
+ {
+ return itable_map;
+ }
+};
+
+#endif // GCJX_AOT_AOTCLASS_HH
Index: aot/aotfactory.cc
===================================================================
RCS file: aot/aotfactory.cc
diff -N aot/aotfactory.cc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ aot/aotfactory.cc 30 Jan 2005 02:21:09 -0000
@@ -0,0 +1,52 @@
+// Factory for creating class wrappers.
+
+// Copyright (C) 2005 Free Software Foundation, Inc.
+//
+// This file is part of GCC.
+//
+// GCC is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2, or (at your option)
+// any later version.
+//
+// GCC 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
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+
+#include "typedefs.hh"
+#include "aot/aotfactory.hh"
+#include "aot/aotclass.hh"
+#include "aot/mangle.hh"
+
+aot_class *
+aot_class_factory::get_class (model_class *klass)
+{
+ std::map<model_class *, aot_class *>::const_iterator it
+ = class_map.find (klass);
+ if (it != class_map.end ())
+ return (*it).second;
+
+ aot_class *result = new aot_class (this, klass);
+ class_map[klass] = result;
+ return result;
+}
+
+template<typename T>
+std::string
+aot_class_factory::get_mangled_form (T *val)
+{
+ std::map<model_element *, std::string>::const_iterator i
+ = mangle_map.find (val);
+ if (i != mangle_map.end ())
+ return (*i).second;
+
+ mangler mg (val);
+ mangle_map[val] = mg.get ();
+ return mg.get ();
+}
Index: aot/aotfactory.hh
===================================================================
RCS file: aot/aotfactory.hh
diff -N aot/aotfactory.hh
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ aot/aotfactory.hh 30 Jan 2005 02:21:09 -0000
@@ -0,0 +1,49 @@
+// Factory for creating class wrappers.
+
+// Copyright (C) 2005 Free Software Foundation, Inc.
+//
+// This file is part of GCC.
+//
+// GCC is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2, or (at your option)
+// any later version.
+//
+// GCC 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
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+
+#ifndef GCJX_AOT_AOTFACTORY_HH
+#define GCJX_AOT_AOTFACTORY_HH
+
+class aot_class;
+
+class aot_class_factory
+{
+ /// Map of classes to class wrappers.
+ std::map<model_class *, aot_class *> class_map;
+
+ /// Map of elements to their mangled forms.
+ std::map<model_element *, std::string> mangle_map;
+
+public:
+
+ aot_class_factory ()
+ {
+ }
+
+ aot_class *get_class (model_class *);
+
+ // Return the mangled form of a method, field, or class.
+ template<typename T>
+ std::string get_mangled_form (T *);
+
+};
+
+#endif // GCJX_AOT_AOTFACTORY_HH
Index: aot/mangle.cc
===================================================================
RCS file: aot/mangle.cc
diff -N aot/mangle.cc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ aot/mangle.cc 30 Jan 2005 02:21:09 -0000
@@ -0,0 +1,240 @@
+// Name mangler that is compatible with g++.
+
+// Copyright (C) 2005 Free Software Foundation, Inc.
+//
+// This file is part of GCC.
+//
+// GCC is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2, or (at your option)
+// any later version.
+//
+// GCC 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
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+
+#include "typedefs.hh"
+#include "aot/mangle.hh"
+
+char
+mangler::get_type_name (model_type *t)
+{
+ assert (t->primitive_p () || t == primitive_void_type);
+
+ if (t == primitive_boolean_type)
+ return 'b';
+ if (t == primitive_byte_type)
+ return 'c';
+ if (t == primitive_char_type)
+ return 'w';
+ if (t == primitive_double_type)
+ return 'd';
+ if (t == primitive_float_type)
+ return 'f';
+ if (t == primitive_int_type)
+ return 'i';
+ if (t == primitive_long_type)
+ return 'x';
+ if (t == primitive_short_type)
+ return 's';
+ if (t == primitive_void_type)
+ return 'v';
+
+ abort ();
+}
+
+void
+mangler::emit_saved (int n)
+{
+ // For N == 0 we emit "S_".
+ // Otherwise we emit S<N>_, where <N> is
+ // the base 36 representation of N - 1.
+ result += "S";
+ if (n > 0)
+ {
+ --n;
+ char out[20];
+ int where = 19;
+ out[where] = '\0';
+ while (n > 0)
+ {
+ int digit = n % 36;
+ out[--where] = digit > 9 ? ('A' + n - 10) : ('0' + n);
+ n /= 36;
+ }
+ if (where == 18)
+ out[--where] = '0';
+ result += &out[where];
+ }
+ result += "_";
+}
+
+int
+mangler::find_compression (model_element *elt, bool is_pointer)
+{
+ int index = 0;
+ for (std::vector<cache_entry>::const_iterator i = compression_table.begin ();
+ i != compression_table.end ();
+ ++i, ++index)
+ {
+ const cache_entry &ce (*i);
+ if (elt == ce.element && is_pointer == ce.is_pointer)
+ return index;
+ }
+ return -1;
+}
+
+void
+mangler::insert (model_element *elt, bool is_pointer)
+{
+ cache_entry ent;
+ ent.element = elt;
+ ent.is_pointer = is_pointer;
+ compression_table.push_back (ent);
+}
+
+void
+mangler::update (const std::string &s)
+{
+ char buf[20];
+ sprintf (buf, "%d", s.length ());
+ result += buf + s;
+}
+
+void
+mangler::update (model_package *p)
+{
+ int n = find_compression (p, false);
+ if (n >= 0)
+ emit_saved (n);
+ else
+ {
+ if (p->get_parent ())
+ update (p->get_parent ());
+ update (p->get_simple_name ());
+ insert (p, false);
+ }
+}
+
+void
+mangler::update_array (model_array_type *t)
+{
+ int n = find_compression (t, true);
+ if (n >= 0)
+ emit_saved (n);
+ else
+ {
+ // Handle the 'JArray' part specially, by representing the
+ // element as NULL.
+ result += "P";
+ n = find_compression (NULL, true);
+ if (n >= 0)
+ emit_saved (n);
+ else
+ {
+ insert (NULL, true);
+ result += "6JArrayI";
+ update (t->element_type (), true);
+ result += "E";
+ insert (t, true);
+ }
+ }
+}
+
+void
+mangler::update (model_type *t, bool is_pointer)
+{
+ if (t->primitive_p () || t == primitive_void_type)
+ result += get_type_name (t);
+ else if (t->array_p ())
+ {
+ // Always a pointer in this case.
+ assert (is_pointer);
+ update_array (assert_cast<model_array_type *> (t));
+ }
+ else
+ {
+ bool enter = false;
+ if (is_pointer)
+ {
+ int n = find_compression (t, true);
+ if (n >= 0)
+ {
+ emit_saved (n);
+ return;
+ }
+ result += "P";
+ enter = true;
+ }
+ int n = find_compression (t, false);
+ if (n >= 0)
+ emit_saved (n);
+ else
+ {
+ result += "N";
+ model_class *k = assert_cast<model_class *> (t);
+ if (k->get_package ())
+ update (k->get_package ());
+ result += k->get_name ();
+ enter = true;
+ // This is a hack: we know only the outer-most class
+ // reference will be called with is_pointer == false.
+ if (is_pointer)
+ result += "E";
+ }
+
+ if (enter)
+ insert (t, is_pointer);
+ }
+}
+
+mangler::mangler (model_type *t)
+ : result ("_Z")
+{
+ assert (t->reference_p ());
+ update (t, false);
+ // We assume this is a reference to 'Name.class'.
+ result += "6class$E";
+}
+
+mangler::mangler (model_method *m)
+ : result ("_Z")
+{
+ // Emit the declaring class.
+ update (m->get_declaring_class (), false);
+
+ // Emit the name, or the special name we use for a constructor.
+ if (m->constructor_p ())
+ result += "C1";
+ else
+ update (m->get_name ());
+
+ result += "E";
+
+ // Emit the argument types.
+ std::list<ref_variable_decl> params = m->get_parameters ();
+ // Special case for no arguments.
+ if (params.empty ())
+ update (primitive_void_type, true);
+ else
+ {
+ for (std::list<ref_variable_decl>::const_iterator i = params.begin ();
+ i != params.end ();
+ ++i)
+ update ((*i)->type (), true);
+ }
+}
+
+mangler::mangler (model_field *f)
+ : result ("_Z")
+{
+ update (f->get_declaring_class (), false);
+ update (f->get_name ());
+ result += "E";
+}
Index: aot/mangle.hh
===================================================================
RCS file: aot/mangle.hh
diff -N aot/mangle.hh
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ aot/mangle.hh 30 Jan 2005 02:21:09 -0000
@@ -0,0 +1,62 @@
+// Name mangler that is compatible with g++.
+
+// Copyright (C) 2005 Free Software Foundation, Inc.
+//
+// This file is part of GCC.
+//
+// GCC is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2, or (at your option)
+// any later version.
+//
+// GCC 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
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+
+#ifndef GCJX_AOT_MANGLE_HH
+#define GCJX_AOT_MANGLE_HH
+
+class mangler
+{
+ // The mangled form.
+ std::string result;
+
+ struct cache_entry
+ {
+ model_element *element;
+ bool is_pointer;
+ };
+
+ std::vector<cache_entry> compression_table;
+
+
+ char get_type_name (model_type *);
+ void emit_saved (int);
+ int find_compression (model_element *, bool);
+ void insert (model_element *, bool);
+ void update (const std::string &);
+ void update (model_package *);
+ void update_array (model_array_type *);
+ void update (model_type *, bool);
+
+public:
+
+ mangler (model_type *);
+
+ mangler (model_method *);
+
+ mangler (model_field *);
+
+ std::string get () const
+ {
+ return result;
+ }
+};
+
+#endif // GCJX_AOT_MANGLE_HH