Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'mcs/ilasm/codegen/ClassTable.cs')
-rw-r--r--mcs/ilasm/codegen/ClassTable.cs250
1 files changed, 250 insertions, 0 deletions
diff --git a/mcs/ilasm/codegen/ClassTable.cs b/mcs/ilasm/codegen/ClassTable.cs
new file mode 100644
index 00000000000..0c2b5adcaca
--- /dev/null
+++ b/mcs/ilasm/codegen/ClassTable.cs
@@ -0,0 +1,250 @@
+//
+// Mono.ILASM.ClassTable.cs
+//
+// Author(s):
+// Jackson Harper (Jackson@LatitudeGeo.com)
+//
+// (C) 2003 Jackson Harper, All rights reserved
+//
+
+using PEAPI;
+using System;
+using System.Collections;
+
+namespace Mono.ILASM {
+
+ public class ClassTable {
+
+ private class ClassTableItem {
+
+ private static readonly int DefinedFlag = 2;
+
+ private int flags;
+
+ public ArrayList LocationList;
+ public ClassDef Class;
+ public MethodTable method_table;
+ public FieldTable field_table;
+
+ public ClassTableItem (ClassDef klass, Location location)
+ {
+ flags = 0;
+ Class = klass;
+ LocationList = new ArrayList ();
+ LocationList.Add (location);
+ method_table = new MethodTable (klass);
+ field_table = new FieldTable (klass);
+ }
+
+ public bool Defined {
+ get { return ((flags & DefinedFlag) != 0); }
+ set {
+ if (value)
+ flags |= DefinedFlag;
+ else
+ flags ^= DefinedFlag;
+ }
+ }
+
+ public bool CheckDefined ()
+ {
+ if (!Defined)
+ return false;
+
+ if (!FieldTable.CheckDefined ())
+ return false;
+
+ if (!MethodTable.CheckDefined ())
+ return false;
+
+ return true;
+ }
+
+ public MethodTable MethodTable {
+ get { return method_table; }
+ }
+
+ public FieldTable FieldTable {
+ get { return field_table; }
+ }
+
+ }
+
+ protected readonly TypeAttr DefaultAttr;
+ protected Hashtable table;
+ protected PEFile pefile;
+
+ public ClassTable (PEFile pefile)
+ {
+ DefaultAttr = TypeAttr.Public;
+ this.pefile = pefile;
+ table = new Hashtable ();
+ }
+
+ public Class Get (string full_name)
+ {
+ ClassTableItem item = table[full_name] as ClassTableItem;
+
+ if (item == null)
+ return null;
+
+ return item.Class;
+ }
+
+ public Class GetReference (string full_name, Location location)
+ {
+ ClassTableItem item = table[full_name] as ClassTableItem;
+
+ if (item != null) {
+ item.LocationList.Add (location);
+ return item.Class;
+ }
+
+ string name_space, name;
+ GetNameAndNamespace (full_name, out name_space, out name);
+ ClassDef klass = pefile.AddClass (DefaultAttr, name_space, name);
+ AddReference (full_name, klass, location);
+
+ return klass;
+ }
+
+ public MethodTable GetMethodTable (string full_name, Location location)
+ {
+ ClassTableItem item = table[full_name] as ClassTableItem;
+
+ if (item == null) {
+ GetReference (full_name, location);
+ return GetMethodTable (full_name, location);
+ }
+
+ return item.MethodTable;
+ }
+
+ public FieldTable GetFieldTable (string full_name, Location location)
+ {
+ ClassTableItem item = table[full_name] as ClassTableItem;
+
+ if (item == null) {
+ GetReference (full_name, location);
+ return GetFieldTable (full_name, location);
+ }
+
+ return item.FieldTable;
+ }
+
+ public ClassDef AddDefinition (string name_space, string name,
+ TypeAttr attr, Location location)
+ {
+ string full_name;
+
+ if (name_space != null)
+ full_name = String.Format ("{0}.{1}", name_space, name);
+ else
+ full_name = name;
+
+ ClassTableItem item = (ClassTableItem) table[full_name];
+
+ if (item == null) {
+ ClassDef klass = pefile.AddClass (attr, name_space, name);
+ AddDefined (full_name, klass, location);
+ return klass;
+ }
+
+ item.Class.AddAttribute (attr);
+ item.Defined = true;
+
+ return item.Class;
+ }
+
+ public ClassDef AddDefinition (string name_space, string name,
+ TypeAttr attr, Class parent, Location location)
+ {
+ string full_name;
+
+ if (name_space != null)
+ full_name = String.Format ("{0}.{1}", name_space, name);
+ else
+ full_name = name;
+
+ ClassTableItem item = (ClassTableItem) table[full_name];
+
+ if (item == null) {
+ ClassDef klass = pefile.AddClass (attr, name_space, name, parent);
+ AddDefined (full_name, klass, location);
+ return klass;
+ }
+
+ /// TODO: Need to set parent, will need to modify PEAPI for this.
+ item.Class.AddAttribute (attr);
+ item.Defined = true;
+
+ return item.Class;
+ }
+
+ /// <summary>
+ /// When there is no code left to compile, check to make sure referenced types where defined
+ /// TODO: Proper error reporting
+ /// </summary>
+ public void CheckForUndefined ()
+ {
+ foreach (DictionaryEntry dic_entry in table) {
+ ClassTableItem table_item = (ClassTableItem) dic_entry.Value;
+ if (table_item.CheckDefined ())
+ continue;
+ Report.Error (String.Format ("Type: {0} is not defined.", dic_entry.Key));
+ }
+ }
+
+ /// <summary>
+ /// If a type is allready defined throw an Error
+ /// </summary>
+ protected void CheckExists (string full_name)
+ {
+ ClassTableItem item = table[full_name] as ClassTableItem;
+
+ if ((item != null) && (item.Defined)) {
+ Report.Error (String.Format ("Class: {0} defined in multiple locations.",
+ full_name));
+ }
+ }
+
+ protected void AddDefined (string full_name, ClassDef klass, Location location)
+ {
+ if (table.Contains (full_name))
+ return;
+
+ ClassTableItem item = new ClassTableItem (klass, location);
+ item.Defined = true;
+
+ table[full_name] = item;
+ }
+
+ protected void AddReference (string full_name, ClassDef klass, Location location)
+ {
+ if (table.Contains (full_name))
+ return;
+
+ ClassTableItem item = new ClassTableItem (klass, location);
+
+ table[full_name] = item;
+ }
+
+ public static void GetNameAndNamespace (string full_name,
+ out string name_space, out string name) {
+
+ int last_dot = full_name.LastIndexOf ('.');
+
+ if (last_dot < 0) {
+ name_space = String.Empty;
+ name = full_name;
+ return;
+ }
+
+ name_space = full_name.Substring (0, last_dot);
+ name = full_name.Substring (last_dot + 1);
+ }
+
+ }
+
+}
+