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:
authorMiguel de Icaza <miguel@gnome.org>2001-08-23 03:32:44 +0400
committerMiguel de Icaza <miguel@gnome.org>2001-08-23 03:32:44 +0400
commit17228003d38d0727e6e205738a0a63171f443c15 (patch)
tree9d33ec503507201125582b613ba17728b0731de1
parenta026988bb83e90ca31865965233e22a2f7e4e6dd (diff)
2001-08-22 Miguel de Icaza <miguel@ximian.com>
* codegen.cs (EmitCode): New function, will emit the code for a Block of code given a TypeContainer and its ILGenerator. * statement.cs (Block): Standard public readonly optimization. (Block::Block constructors): Link children. (Block::Child): Child Linker. (Block::EmitVariables): Emits IL variable declarations. * class.cs: Drop support for MethodGroups here, delay until Semantic Analysis. (Method::): Applied the same simplification that I did before, and move from Properties to public readonly fields. (Method::ParameterTypes): Returns the parameter types for the function, and implements a cache that will be useful later when I do error checking and the semantic analysis on the methods is performed. (Constructor::GetCallingConvention): Renamed from CallingConvetion and made a method, optional argument tells whether this is a class or a structure to apply the `has-this' bit. (Method::GetCallingConvention): Implement, returns the calling convention. (Method::Define): Defines the type, a second pass is performed later to populate the methods. (Constructor::ParameterTypes): implement a cache similar to the one on Method::ParameterTypes, useful later when we do semantic analysis. (TypeContainer::EmitMethod): New method. Emits methods. * expression.cs: Removed MethodGroup class from here. * parameter.cs (Parameters::GetCallingConvention): new method. svn path=/trunk/mcs/; revision=573
-rwxr-xr-xmcs/mcs/ChangeLog36
-rwxr-xr-xmcs/mcs/cil-codegen.cs48
-rwxr-xr-xmcs/mcs/class.cs244
-rwxr-xr-xmcs/mcs/codegen.cs58
-rwxr-xr-xmcs/mcs/compiler.csproj.user4
-rwxr-xr-xmcs/mcs/cs-parser.jay2
-rwxr-xr-xmcs/mcs/driver.cs3
-rwxr-xr-xmcs/mcs/expression.cs34
-rwxr-xr-xmcs/mcs/gen-treedump.cs21
-rwxr-xr-xmcs/mcs/makefile2
-rwxr-xr-xmcs/mcs/parameter.cs8
-rwxr-xr-xmcs/mcs/rootcontext.cs17
-rwxr-xr-xmcs/mcs/statement.cs148
13 files changed, 395 insertions, 230 deletions
diff --git a/mcs/mcs/ChangeLog b/mcs/mcs/ChangeLog
index 274e9390b54..c1d44645a25 100755
--- a/mcs/mcs/ChangeLog
+++ b/mcs/mcs/ChangeLog
@@ -1,3 +1,39 @@
+2001-08-22 Miguel de Icaza <miguel@ximian.com>
+
+ * codegen.cs (EmitCode): New function, will emit the code for a
+ Block of code given a TypeContainer and its ILGenerator.
+
+ * statement.cs (Block): Standard public readonly optimization.
+ (Block::Block constructors): Link children.
+ (Block::Child): Child Linker.
+ (Block::EmitVariables): Emits IL variable declarations.
+
+ * class.cs: Drop support for MethodGroups here, delay until
+ Semantic Analysis.
+ (Method::): Applied the same simplification that I did before, and
+ move from Properties to public readonly fields.
+ (Method::ParameterTypes): Returns the parameter types for the
+ function, and implements a cache that will be useful later when I
+ do error checking and the semantic analysis on the methods is
+ performed.
+ (Constructor::GetCallingConvention): Renamed from CallingConvetion
+ and made a method, optional argument tells whether this is a class
+ or a structure to apply the `has-this' bit.
+ (Method::GetCallingConvention): Implement, returns the calling
+ convention.
+ (Method::Define): Defines the type, a second pass is performed
+ later to populate the methods.
+
+ (Constructor::ParameterTypes): implement a cache similar to the
+ one on Method::ParameterTypes, useful later when we do semantic
+ analysis.
+
+ (TypeContainer::EmitMethod): New method. Emits methods.
+
+ * expression.cs: Removed MethodGroup class from here.
+
+ * parameter.cs (Parameters::GetCallingConvention): new method.
+
2001-08-21 Miguel de Icaza <miguel@ximian.com>
* class.cs (TypeContainer::Populate): Drop RootContext from the
diff --git a/mcs/mcs/cil-codegen.cs b/mcs/mcs/cil-codegen.cs
deleted file mode 100755
index 5a729be9edf..00000000000
--- a/mcs/mcs/cil-codegen.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-//
-// cil-codegen.cs: The CIL code generation interface
-//
-// Author:
-// Miguel de Icaza (miguel@ximian.com)
-//
-// (C) 2001 Ximian, Inc.
-//
-
-using System;
-using System.Reflection;
-using System.Reflection.Emit;
-
-public class CilCodeGen {
- AppDomain current_domain;
- AssemblyBuilder assembly_builder;
- ModuleBuilder module_builder;
-
- public CilCodeGen (string name, string output)
- {
- AssemblyName an;
-
- an = new AssemblyName ();
- an.Name = "AssemblyName";
- current_domain = AppDomain.CurrentDomain;
- assembly_builder = current_domain.DefineDynamicAssembly (
- an, AssemblyBuilderAccess.RunAndSave);
-
- module_builder = assembly_builder.DefineDynamicModule (name, output);
- }
-
- public AssemblyBuilder AssemblyBuilder {
- get {
- return assembly_builder;
- }
- }
-
- public ModuleBuilder ModuleBuilder {
- get {
- return module_builder;
- }
- }
-
- public void Save (string name)
- {
- assembly_builder.Save (name);
- }
-}
diff --git a/mcs/mcs/class.cs b/mcs/mcs/class.cs
index 8a40fcbb930..05724bc5146 100755
--- a/mcs/mcs/class.cs
+++ b/mcs/mcs/class.cs
@@ -46,8 +46,8 @@ namespace CIR {
// Holds the list of
ArrayList interfaces;
- // Holds the method groups.
- Hashtable method_groups;
+ // Holds the methods.
+ ArrayList methods;
//
// Pointers to the default constructor and the default static constructor
@@ -167,26 +167,15 @@ namespace CIR {
string name = method.Name;
Object value = defined_names [name];
- if (value != null && (!(value is MethodGroup)))
+ if (value != null && (!(value is Method)))
return AdditionResult.NameExists;
- if (method_groups == null)
- method_groups = new Hashtable ();
+ if (methods == null)
+ methods = new ArrayList ();
- MethodGroup mg = (MethodGroup) method_groups [name];
- if (mg == null){
- mg = new MethodGroup (name);
+ methods.Add (method);
+ DefineName (name, method);
- mg.Add (method);
- method_groups.Add (name, mg);
-
- return AdditionResult.Success;
- }
- mg.Add (method);
-
- if (value == null)
- DefineName (name, mg);
-
return AdditionResult.Success;
}
@@ -296,9 +285,9 @@ namespace CIR {
}
}
- public Hashtable MethodGroups {
+ public ArrayList Methods {
get {
- return method_groups;
+ return methods;
}
}
@@ -463,26 +452,14 @@ namespace CIR {
//
void EmitConstructor (Constructor c)
{
- ConstructorBuilder cb;
- MethodAttributes ca = (MethodAttributes.RTSpecialName |
- MethodAttributes.SpecialName);
- bool is_static = (c.ModFlags & Modifiers.STATIC) != 0;
-
- if (is_static)
- ca |= MethodAttributes.Static;
-
- ca |= Modifiers.MethodAttr (c.ModFlags);
-
- cb = TypeBuilder.DefineConstructor (
- ca, c.CallingConvention, c.ParameterTypes (this));
-
- if (is_static){
+ if ((c.ModFlags & Modifiers.STATIC) != 0){
if (initialized_static_fields != null)
- EmitStaticFieldInitializers (cb);
+ EmitStaticFieldInitializers (c.ConstructorBuilder);
} else {
if (initialized_fields != null)
- EmitFieldInitializers (cb);
+ EmitFieldInitializers (c.ConstructorBuilder);
}
+
}
//
@@ -532,16 +509,36 @@ namespace CIR {
if (Constructors != null){
foreach (Constructor c in Constructors)
- EmitConstructor (c);
+ c.Define (this);
}
+ if (Methods != null){
+ foreach (Method m in Methods)
+ m.Define (this);
+ }
+ }
+
+ //
+ // Emits the code, this step is performed after all
+ // the types, enumerations, constructors
+ //
+ public void Emit ()
+ {
if (default_constructor == null)
EmitDefaultConstructor (false);
if (initialized_static_fields != null && default_static_constructor == null)
EmitDefaultConstructor (true);
- }
+ if (Constructors != null)
+ foreach (Constructor c in Constructors)
+ c.Emit ();
+
+ if (Methods != null)
+ foreach (Method m in Methods)
+ m.Emit (this);
+ }
+
public delegate void ExamineType (TypeContainer container, object cback_data);
void WalkTypesAt (TypeContainer root, ExamineType visit, object cback_data)
@@ -645,19 +642,21 @@ namespace CIR {
}
public class Method {
- Parameters parameters;
- string return_type;
- string name;
- int modifiers;
- Block block;
-
+ public readonly Parameters Parameters;
+ public readonly string ReturnType;
+ public readonly string Name;
+ public readonly int ModFlags;
+ public MethodBuilder MethodBuilder;
+
+ Block block;
+
// return_type can be "null" for VOID values.
public Method (string return_type, int mod, string name, Parameters parameters)
{
- this.return_type = return_type;
- this.name = name;
- this.parameters = parameters;
- this.modifiers = Modifiers.Check (AllowedModifiers, mod, Modifiers.PRIVATE);
+ Name = name;
+ ReturnType = return_type;
+ Parameters = parameters;
+ ModFlags = Modifiers.Check (AllowedModifiers, mod, Modifiers.PRIVATE);
}
// <summary>
@@ -686,34 +685,89 @@ namespace CIR {
}
}
- public string Name {
- get {
- return name;
- }
+ //
+ // Returns the `System.Type' for the ReturnType of this
+ // function. Provides a nice cache. (used between semantic analysis
+ // and actual code generation
+ //
+ Type type_return_type;
+ public Type GetReturnType (TypeContainer parent)
+ {
+ if (type_return_type == null)
+ type_return_type = parent.LookupType (ReturnType, false);
+
+ return type_return_type;
}
- public int ModFlags {
- get {
- return modifiers;
- }
+ //
+ // Returns the System.Type array for the parameters of this method
+ //
+ Type [] parameter_types;
+ public Type [] ParameterTypes (TypeContainer parent)
+ {
+ if (Parameters == null)
+ return null;
+
+ if (parameter_types == null)
+ parameter_types = Parameters.GetParameterInfo (parent);
+
+ return parameter_types;
}
- public Parameters Parameters {
- get {
- return parameters;
- }
+ public CallingConventions GetCallingConvention (bool is_class)
+ {
+ CallingConventions cc = 0;
+
+ cc = Parameters.GetCallingConvention ();
+
+ if (is_class)
+ if ((ModFlags & Modifiers.STATIC) != 0)
+ cc |= CallingConventions.HasThis;
+
+ return cc;
}
- public string ReturnType {
- get {
- return return_type;
+ //
+ // Creates the type
+ //
+ public void Define (TypeContainer parent)
+ {
+ Type ret_type = GetReturnType (parent);
+ Type [] parameters = ParameterTypes (parent);
+
+ //
+ // Create the method
+ //
+ MethodBuilder = parent.TypeBuilder.DefineMethod (
+ Name, Modifiers.MethodAttr (ModFlags),
+ GetCallingConvention (parent is Class),
+ ret_type, parameters);
+
+ //
+ // Define each type attribute (in/out/ref) and
+ // the argument names.
+ //
+ Parameter [] p = Parameters.FixedParameters;
+ if (p != null){
+ int i;
+
+ for (i = 0; i < p.Length; i++)
+ MethodBuilder.DefineParameter (
+ i + 1, p [i].Attributes, p [i].Name);
+
+ if (i != parameters.Length)
+ Console.WriteLine ("Implement the type definition for params");
}
}
- public string ArgumentSignature {
- get {
- return ""; // TYPEFIX: Type.MakeParameterSignature (name, parameters);
- }
+ //
+ // Emits the code
+ //
+ public void Emit (TypeContainer parent)
+ {
+ ILGenerator ig = MethodBuilder.GetILGenerator ();
+
+ CodeGen.EmitCode (parent, ig, block);
}
}
@@ -772,6 +826,7 @@ namespace CIR {
}
public class Constructor {
+ public ConstructorBuilder ConstructorBuilder;
public readonly ConstructorInitializer Initializer;
public readonly Parameters Parameters;
public readonly string Name;
@@ -829,27 +884,60 @@ namespace CIR {
}
}
- public CallingConventions CallingConvention {
- get {
- CallingConventions cc = 0;
-
- if (Parameters.ArrayParameter != null)
- cc |= CallingConventions.VarArgs;
- else
- cc |= CallingConventions.Standard;
+ public CallingConventions GetCallingConvention (bool parent_is_class)
+ {
+ CallingConventions cc = 0;
+
+ if (Parameters.ArrayParameter != null)
+ cc |= CallingConventions.VarArgs;
+ else
+ cc |= CallingConventions.Standard;
+ if (parent_is_class)
if ((ModFlags & Modifiers.STATIC) != 0)
cc |= CallingConventions.HasThis;
// FIXME: How is `ExplicitThis' used in C#?
- return cc;
- }
+ return cc;
}
+ //
+ // Cached representation
+ ///
+ Type [] parameter_types;
public Type [] ParameterTypes (TypeContainer tc)
{
- return Parameters.GetParameterInfo (tc);
+ if (Parameters == null)
+ return null;
+
+ if (parameter_types == null)
+ parameter_types = Parameters.GetParameterInfo (tc);
+
+ return parameter_types;
+ }
+
+ //
+ // Creates the ConstructorBuilder
+ //
+ public void Define (TypeContainer parent)
+ {
+ MethodAttributes ca = (MethodAttributes.RTSpecialName |
+ MethodAttributes.SpecialName);
+
+ if ((ModFlags & Modifiers.STATIC) != 0)
+ ca |= MethodAttributes.Static;
+
+ ConstructorBuilder = parent.TypeBuilder.DefineConstructor (
+ ca, GetCallingConvention (parent is Class),
+ ParameterTypes (parent));
+ }
+
+ //
+ // Emits the code
+ //
+ public void Emit ()
+ {
}
}
diff --git a/mcs/mcs/codegen.cs b/mcs/mcs/codegen.cs
new file mode 100755
index 00000000000..1f36bde8c6d
--- /dev/null
+++ b/mcs/mcs/codegen.cs
@@ -0,0 +1,58 @@
+//
+// codegen.cs: The code generator
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+using System;
+using System.Reflection;
+using System.Reflection.Emit;
+
+namespace CIR {
+
+ public class CodeGen {
+ AppDomain current_domain;
+ AssemblyBuilder assembly_builder;
+ ModuleBuilder module_builder;
+
+ public CodeGen (string name, string output)
+ {
+ AssemblyName an;
+
+ an = new AssemblyName ();
+ an.Name = "AssemblyName";
+ current_domain = AppDomain.CurrentDomain;
+ assembly_builder = current_domain.DefineDynamicAssembly (
+ an, AssemblyBuilderAccess.RunAndSave);
+
+ module_builder = assembly_builder.DefineDynamicModule (name, output);
+ }
+
+ public AssemblyBuilder AssemblyBuilder {
+ get {
+ return assembly_builder;
+ }
+ }
+
+ public ModuleBuilder ModuleBuilder {
+ get {
+ return module_builder;
+ }
+ }
+
+ public void Save (string name)
+ {
+ assembly_builder.Save (name);
+ }
+
+ public static void EmitCode (TypeContainer parent, ILGenerator ig, Block block)
+ {
+ block.EmitVariables (parent, ig);
+
+ ig.Emit (OpCodes.Ret);
+ }
+ }
+}
diff --git a/mcs/mcs/compiler.csproj.user b/mcs/mcs/compiler.csproj.user
index 1357db4344b..0c76164add8 100755
--- a/mcs/mcs/compiler.csproj.user
+++ b/mcs/mcs/compiler.csproj.user
@@ -9,11 +9,11 @@
EnableUnmanagedDebugging = "false"
EnableSQLServerDebugging = "false"
StartAction = "Project"
- StartArguments = ""
+ StartArguments = "i-undefined.cs"
StartPage = ""
StartProgram = ""
StartURL = ""
- StartWorkingDirectory = ""
+ StartWorkingDirectory = "c:\mono\mcs\tests"
StartWithIE = "false"
/>
<Config
diff --git a/mcs/mcs/cs-parser.jay b/mcs/mcs/cs-parser.jay
index a536c9ec12b..31cfc646fa9 100755
--- a/mcs/mcs/cs-parser.jay
+++ b/mcs/mcs/cs-parser.jay
@@ -664,7 +664,7 @@ method_header
member_name
OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
{
- Method method = new Method ("void", (int) $2, (string) $4, (Parameters) $6);
+ Method method = new Method ("System.Void", (int) $2, (string) $4, (Parameters) $6);
current_local_parameters = (Parameters) $6;
$$ = method;
diff --git a/mcs/mcs/driver.cs b/mcs/mcs/driver.cs
index e06b56007fe..5a9bfc0e72d 100755
--- a/mcs/mcs/driver.cs
+++ b/mcs/mcs/driver.cs
@@ -286,13 +286,14 @@ namespace CIR
if (output_file == null)
output_file = "a.exe";
- context.CodeGen = new CilCodeGen (output_file, output_file);
+ context.CodeGen = new CodeGen (output_file, output_file);
//
// The second pass of the compiler
//
context.ResolveTree ();
context.PopulateTypes ();
+ context.EmitCode ();
if (context.Report.Errors > 0){
error ("Compilation failed");
diff --git a/mcs/mcs/expression.cs b/mcs/mcs/expression.cs
index 52e0b17ad83..05f15941b07 100755
--- a/mcs/mcs/expression.cs
+++ b/mcs/mcs/expression.cs
@@ -457,40 +457,6 @@ namespace CIR {
}
}
}
-
- public class MethodGroup : Expression {
- Hashtable signatures;
- string name;
-
- public MethodGroup (string name)
- {
- signatures = new Hashtable ();
- this.name = name;
- }
-
- public bool Add (Method method)
- {
- string sig = method.ArgumentSignature;
-
- if (signatures.Contains (sig))
- return false;
-
- signatures.Add (sig, method);
- return true;
- }
-
- public string Name {
- get {
- return name;
- }
- }
-
- public Hashtable Methods {
- get {
- return signatures;
- }
- }
- }
}
diff --git a/mcs/mcs/gen-treedump.cs b/mcs/mcs/gen-treedump.cs
index 9121a2322d9..5f0a38f290c 100755
--- a/mcs/mcs/gen-treedump.cs
+++ b/mcs/mcs/gen-treedump.cs
@@ -631,9 +631,11 @@ namespace Generator {
if (b.Variables != null){
foreach (DictionaryEntry entry in b.Variables){
+ VariableInfo vi = (VariableInfo) entry.Value;
+
space ();
output_newline (
- (string) entry.Value + " " +
+ vi.Type + " " +
(string) entry.Key + ";");
}
newline ();
@@ -664,15 +666,6 @@ namespace Generator {
newline ();
}
- void GenerateMethodGroup (MethodGroup mg)
- {
- foreach (DictionaryEntry de in mg.Methods){
- Method m = (Method) de.Value;
-
- GenerateMethod (m);
- }
- }
-
void GenerateInterfaceMethod (InterfaceMethod imethod)
{
space ();
@@ -883,11 +876,9 @@ namespace Generator {
GenerateFromTypes (tc);
- if (tc.MethodGroups != null){
- foreach (DictionaryEntry de in tc.MethodGroups){
- MethodGroup mg = (MethodGroup) de.Value;
-
- GenerateMethodGroup (mg);
+ if (tc.Methods != null){
+ foreach (Method m in tc.Methods){
+ GenerateMethod (m);
}
}
}
diff --git a/mcs/mcs/makefile b/mcs/mcs/makefile
index 6c8c246e2c5..0694b75a3fb 100755
--- a/mcs/mcs/makefile
+++ b/mcs/mcs/makefile
@@ -10,7 +10,7 @@ COMPILER_SOURCES = \
assign.cs \
driver.cs $(COMMON_SOURCES) \
class.cs \
- cil-codegen.cs \
+ codegen.cs \
constant.cs \
decl.cs \
enum.cs \
diff --git a/mcs/mcs/parameter.cs b/mcs/mcs/parameter.cs
index 2c3a6b2b1ae..8e3d1811825 100755
--- a/mcs/mcs/parameter.cs
+++ b/mcs/mcs/parameter.cs
@@ -166,6 +166,14 @@ namespace CIR {
return types;
}
+
+ public CallingConventions GetCallingConvention ()
+ {
+ if (ArrayParameter != null)
+ return CallingConventions.VarArgs;
+ else
+ return CallingConventions.Standard;
+ }
}
}
diff --git a/mcs/mcs/rootcontext.cs b/mcs/mcs/rootcontext.cs
index 6174555e386..0fa5a5a4117 100755
--- a/mcs/mcs/rootcontext.cs
+++ b/mcs/mcs/rootcontext.cs
@@ -30,7 +30,7 @@ namespace CIR {
//
// The System.Reflection.Emit CodeGenerator
//
- CilCodeGen cg;
+ CodeGen cg;
//
// The module builder pointer
@@ -78,7 +78,7 @@ namespace CIR {
}
}
- public CilCodeGen CodeGen {
+ public CodeGen CodeGen {
get {
return cg;
}
@@ -583,6 +583,19 @@ namespace CIR {
}
}
+ public void EmitCode ()
+ {
+ Hashtable classes;
+
+ if ((classes = tree.Classes) != null){
+ foreach (DictionaryEntry de in classes){
+ TypeContainer tc = (TypeContainer) de.Value;
+
+ tc.Emit ();
+ }
+ }
+ }
+
// <summary>
// Compiling against Standard Libraries property.
// </summary>
diff --git a/mcs/mcs/statement.cs b/mcs/mcs/statement.cs
index d6d5842f931..d8a5bbd6df0 100755
--- a/mcs/mcs/statement.cs
+++ b/mcs/mcs/statement.cs
@@ -8,6 +8,8 @@
//
using System;
+using System.Reflection;
+using System.Reflection.Emit;
namespace CIR {
@@ -213,58 +215,91 @@ namespace CIR {
}
}
+ public struct VariableInfo {
+ public readonly string Type;
+ public LocalBuilder LocalBuilder ;
+
+ public VariableInfo (string type)
+ {
+ Type = type;
+ LocalBuilder = null;
+ }
+ }
+
// <summary>
// Used for Label management
// </summary>
//
public class Block : Statement {
- Block parent;
+ public readonly Block Parent;
+ public readonly bool Implicit;
+ public readonly string Label;
+
+ //
+ // The statements in this block
+ //
StatementCollection statements;
+
+ //
+ // Labels. (label, block) pairs.
+ //
Hashtable labels;
- Hashtable labels_referenced;
- bool implicit_block;
+
+ //
+ // Keeps track of (name, type) pairs
+ //
Hashtable variables;
- string label;
- int internal_id_serial;
- bool used = false;
+
+ //
+ // Maps variable names to ILGenerator.LocalBuilders
+ //
+ Hashtable local_builders;
+
+ //
+ // If we have a child, here it is
+ //
+ Block child;
+ bool used = false;
+
public Block (Block parent)
{
- this.parent = parent;
- this.implicit_block = false;
+ if (parent != null)
+ parent.Child = this;
+
+ this.Parent = parent;
+ this.Implicit = false;
}
public Block (Block parent, bool implicit_block)
{
- this.parent = parent;
- this.implicit_block = true;
+ if (parent != null)
+ parent.Child = this;
+
+ this.Parent = parent;
+ this.Implicit = true;
}
public Block (Block parent, string labeled)
{
- this.parent = parent;
- this.implicit_block = true;
- label = labeled;
+ if (parent != null)
+ parent.Child = this;
+
+ this.Parent = parent;
+ this.Implicit = true;
+ Label = labeled;
}
- public Block Parent {
+ public Block Child {
get {
- return parent;
+ return child;
}
- }
- public bool Implicit {
- get {
- return implicit_block;
+ set {
+ child = value;
}
}
- public string Label {
- get {
- return label;
- }
- }
-
// <summary>
// Adds a label to the current block.
// </summary>
@@ -292,8 +327,10 @@ namespace CIR {
if (GetVariableType (name) != null)
return false;
+
+ VariableInfo vi = new VariableInfo (type);
- variables.Add (name, type);
+ variables.Add (name, vi);
return true;
}
@@ -311,8 +348,8 @@ namespace CIR {
type = (string) variables [name];
if (type != null)
return type;
- else if (parent != null)
- return parent.GetVariableType (name);
+ else if (Parent != null)
+ return Parent.GetVariableType (name);
return null;
}
@@ -334,31 +371,13 @@ namespace CIR {
}
}
- // <summary>
- // Call this to label the label as used in a block
- // </summary>
- public void Reference (string name)
- {
- if (labels_referenced == null)
- labels_referenced = new Hashtable ();
- labels_referenced.Add (name, null);
- }
-
// <returns>
// A list of labels that were not used within this block
// </returns>
public string [] GetUnreferenced ()
{
- ArrayList unrefs = new ArrayList ();
-
- foreach (string s in (string []) labels.Keys) {
- if (labels_referenced [s] == null)
- unrefs.Add (s);
- }
-
- string [] result = new string [unrefs.Count];
- unrefs.CopyTo (result);
- return result;
+ // FIXME: Implement me
+ return null;
}
public StatementCollection Statements {
@@ -390,12 +409,45 @@ namespace CIR {
// used to create temporary variables that should not
// be seen by the application
// </summary
+ int internal_id_serial;
public string MakeInternalID () {
string ret = internal_id_serial.ToString ();
internal_id_serial++;
return "0_" + ret;
}
+
+ // <summary>
+ // Emits the variable declarations
+ // </summary>
+
+ public void EmitVariables (TypeContainer tc, ILGenerator ig)
+ {
+ //
+ // Process this block variables
+ //
+ if (variables != null){
+ local_builders = new Hashtable ();
+
+ foreach (DictionaryEntry de in variables){
+ string name = (string) de.Key;
+ VariableInfo vi = (VariableInfo) de.Value;
+ Type t;
+
+ t = tc.LookupType (vi.Type, false);
+ if (t == null)
+ continue;
+
+ vi.LocalBuilder = ig.DeclareLocal (t);
+ }
+ }
+
+ //
+ // Now, handle the children
+ //
+ if (Child != null)
+ Child.EmitVariables (tc, ig);
+ }
}
public class SwitchLabel {