dotgnu-pnet-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[dotgnu-pnet-commits] [SCM] DotGNU Portable.NET engine, compilers and to


From: Klaus Treichel
Subject: [dotgnu-pnet-commits] [SCM] DotGNU Portable.NET engine, compilers and tools (pnet) branch, master, updated. 583820da7c37f3a81b18c8d2f20dbd1e27f20673
Date: Mon, 10 Aug 2009 18:46:40 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "DotGNU Portable.NET engine, compilers and tools (pnet)".

The branch, master has been updated
       via  583820da7c37f3a81b18c8d2f20dbd1e27f20673 (commit)
      from  bbe244d80c0d5f2e49558f5537e6db009832a1a8 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.savannah.gnu.org/cgit/pnet.git/commit/?id=583820da7c37f3a81b18c8d2f20dbd1e27f20673

commit 583820da7c37f3a81b18c8d2f20dbd1e27f20673
Author: Klaus Treichel <address@hidden>
Date:   Mon Aug 10 20:38:36 2009 +0200

    Fix using statements with more than one resource.
    Add support for the local var type.

diff --git a/ChangeLog b/ChangeLog
index 1ac303a..997f776 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,60 @@
+2009-08-10  Klaus Treichel  <address@hidden>
+
+       * codegen/cg_nodes.tc (ILNode_VariableDeclarator): Added.
+
+       * codegen/cg_stmt.tc (ILNode_GenDiscard(ILNode_LocalVarDeclaration)):
+       Add generation of the discard code on varnames.
+       (ILNode_GenDiscard(ILNode_VariableDeclarator)): Added
+
+       * codegen/jv_stmt.tc (JavaGenDiscard(ILNode_LocalVarDeclaration)):
+       Add generation of the discard code on varnames.
+       (JavaGenDiscard(ILNode_VariableDeclarator)): Added
+
+       * cscc/c/c_stubs (ILNode_CSemAnalysis(ILNode_VariableDeclarator)):
+       Add to stubs.
+
+       * cscc/csharp/cs_defs.tc (ILNode_ResourceDeclaration): Remove init
+       member.
+       (ILNode_UsingStatement): Replaces old ILNode_Using.
+       (ILNode_Using): Add to handle one resource in a using statement.
+
+       * cscc/csharp/cs_gather.c: Do some reformatting.
+
+       * cscc/csharp/cs_grammar.y: Use the new ILNode_VariableDeclarator for
+       a variable declaration and make VariableDeclarations an ILNode_List of
+       variable declarations.
+       Replace creation of Using nodes by UsingStatement nodes.
+
+       * cscc/csharp/cs_lvalue.tc (ILNode_SemAnalyzis(ILNode_LocalVar)): Return
+       a semantic value with the type of the local variable now.
+
+       * cscc/csharp/cs_modifiers.c (ModifierError): Add handling of the new
+       partial modifier.
+
+       * cscc/csharp/cs_stmt.tc (AddLocalToMethod): Added to replace individual
+       implementations in various places.
+       (HandleFixedExpr, ILNode_SemAnalysis(ILNode_CatchClause),
+       ILNode_SemAnalysis(ILNode_Fixed)) : like here
+       (CheckIfDisposable): Add to check if a type implements the
+       System.IDisposable interface and print an error if doesn't.
+       (FindLocalType): Add function to find a local type incl. handling of the
+       var type.
+       (HandleLocalDecl): Added to handle the declaration of a local with var
+       type handling.
+       (HandleForeachVarDecl): Added to handle declaration of the foreach 
indexer
+       variable.
+       (ILNode_SemAnalysis(ILNode_Foreach)): Add handling of the local var 
type.
+       (ILNode_SemAnalysis(ILNode_UsingStatement)): Convert the declared
+       resources to a number of nested ILNode_Using nodes now.
+       (ILNode_GenDiscard(ILNode_UsingStatement)): Generate the discard code 
on 
+       the resources which have been  replaced by using nodes during
+       semanalyzing.
+       (ILNode_GenDiscard(ILNode_Using)): Generate discard code for one 
declared
+       resource.
+       (ILNode_SemAnalysis(ILNode_VariableDeclarator)): Added
+       (ILNode_SemAnalysis(ILNode_ResourceDeclaration)): Code removed because
+       it is handled completely now in 
ILNode_SemAnalysis(ILNode_UsingStatement).
+
 2009-08-01  Klaus Treichel  <address@hidden>
 
        * codegen/cs_decls.tc (DumpClassMembers): Add helper function for 
dumping
diff --git a/codegen/cg_nodes.tc b/codegen/cg_nodes.tc
index 30784b3..7153daf 100644
--- a/codegen/cg_nodes.tc
+++ b/codegen/cg_nodes.tc
@@ -818,6 +818,11 @@ struct _tagILSwitchValue
        ILNode *expr;
        ILNode *stmt;
 }
+%node ILNode_VariableDeclarator ILNode_Statement =
+{
+       ILNode     *name;
+       ILNode     *init;
+}
 %node ILNode_LocalVarDeclaration ILNode_Statement =
 {
        ILNode     *type;
diff --git a/codegen/cg_stmt.tc b/codegen/cg_stmt.tc
index 0a361fb..5f2b583 100644
--- a/codegen/cg_stmt.tc
+++ b/codegen/cg_stmt.tc
@@ -2638,11 +2638,21 @@ ILNode_EndsInReturnImpl(ILNode_Lock)
 }
 
 /*
- * Generate discard code for local variable declarations.
+ * Generate discard code for variable declarators.
  */
+ILNode_GenDiscard(ILNode_VariableDeclarator)
+{
+       /*
+        * Nothing to do here: the node will be replaced during semantic
+        * analysis if some action is needed.
+        */
+}
 ILNode_GenDiscard(ILNode_LocalVarDeclaration)
 {
-       /* Nothing to do here: the declaration is done in the method header */
+       if(node->varNames)
+       {
+               ILNode_GenDiscard(node->varNames, info);
+       }
 }
 
 /*
diff --git a/codegen/jv_stmt.tc b/codegen/jv_stmt.tc
index 08e869d..d3a6690 100644
--- a/codegen/jv_stmt.tc
+++ b/codegen/jv_stmt.tc
@@ -1736,11 +1736,24 @@ JavaGenDiscard(ILNode_Lock)
 }
 
 /*
+ * Generate discard code for variable declarators.
+ */
+JavaGenDiscard(ILNode_VariableDeclarator)
+{
+       /*
+        * Nothing to do here: the node will be replaced during semantic
+        * analysis if some action is needed.
+        */
+}
+/*
  * Generate discard code for local variable declarations.
  */
 JavaGenDiscard(ILNode_LocalVarDeclaration)
 {
-       /* Nothing to do here: the declaration is done in the method header */
+       if(node->varNames)
+       {
+               JavaGenDiscard(node->varNames, info);
+       }
 }
 
 /*
diff --git a/cscc/c/c_stubs.tc b/cscc/c/c_stubs.tc
index bff6ddd..5166a8d 100644
--- a/cscc/c/c_stubs.tc
+++ b/cscc/c/c_stubs.tc
@@ -96,6 +96,7 @@ ILNode_CSemAnalysis(ILNode_GotoDefault),
 ILNode_CSemAnalysis(ILNode_SwitchSectList),
 ILNode_CSemAnalysis(ILNode_SwitchSection),
 ILNode_CSemAnalysis(ILNode_CaseList),
+ILNode_CSemAnalysis(ILNode_VariableDeclarator),
 ILNode_CSemAnalysis(ILNode_LocalVarDeclaration),
 ILNode_CSemAnalysis(ILNode_LocalConstDeclaration),
 ILNode_CSemAnalysis(ILNode_QualIdent),
diff --git a/cscc/csharp/cs_defs.tc b/cscc/csharp/cs_defs.tc
index 4ceaa00..5ac4fd3 100644
--- a/cscc/csharp/cs_defs.tc
+++ b/cscc/csharp/cs_defs.tc
@@ -154,13 +154,20 @@
 {
        ILNode *type;
        ILNode *variables;
-       ILNode *init;
 }
-%node ILNode_Using ILNode_Statement =
+%node ILNode_UsingStatement ILNode_Statement =
 {
        ILNode *resource;
        ILNode *stmt;
 }
+%node ILNode_Using ILNode_Statement =
+{
+       ILNode_LocalVar    *localVar;
+       ILNode                     *init;
+       ILNode                     *stmt;
+       ILType                     *type;
+}
+
 %node ILNode_Unsafe ILNode_Statement =
 {
        ILNode *stmt;
@@ -188,7 +195,7 @@
        ILNode_Namespace *enclosing;
        %nocreate ILNode_UsingNamespace *using = {0};
        %nocreate ILNode_Alias *alias = {0};
-       %nocreate ILScope *localScope={0};
+       %nocreate ILScope *localScope = {0};
 }
 %node ILNode_UsingAlias ILNode_Alias =
 {
diff --git a/cscc/csharp/cs_gather.c b/cscc/csharp/cs_gather.c
index 2af9fb5..0a9d3bc 100644
--- a/cscc/csharp/cs_gather.c
+++ b/cscc/csharp/cs_gather.c
@@ -2194,7 +2194,7 @@ static void CreateMethod(ILGenInfo *info, 
ILNode_ClassDefn *classNode,
                                         IL_META_MEMBERKIND_METHOD, ".ctor", 
0)) != 0)
                {
                        if((ILMethod_Token(methodInfo) & IL_META_TOKEN_MASK) ==
-                                       IL_META_TOKEN_MEMBER_REF)
+                                       IL_META_TOKEN_MEMBER_REF)
                        {
                                if(!ILMethodNewToken(methodInfo))
                                {
diff --git a/cscc/csharp/cs_grammar.y b/cscc/csharp/cs_grammar.y
index c9b9881..f543b10 100644
--- a/cscc/csharp/cs_grammar.y
+++ b/cscc/csharp/cs_grammar.y
@@ -1249,7 +1249,7 @@ static ILNode_GenericTypeParameters 
*TypeActualsToTypeFormals(ILNode *typeArgume
 %type <genericMethodHeaderStart> GenericMethodHeaderStart
 %type <node>           ConstantDeclaration ConstantDeclarators 
ConstantDeclarator
 %type <node>           FieldDeclaration FieldDeclarators FieldDeclarator
-%type <varInit>                VariableDeclarators VariableDeclarator
+%type <node>           VariableDeclarators VariableDeclarator
 %type <node>           VariableInitializer LocalVariableDeclaration
 %type <node>           LocalConstantDeclaration
 %type <node>           EventFieldDeclaration EventDeclaration 
@@ -2558,60 +2558,32 @@ InnerEmbeddedStatement
 
 LocalVariableDeclaration
        : LocalVariableType VariableDeclarators         {
-                               /* "VariableDeclarators" has split the 
declaration into
-                                  a list of variable names, plus a list of 
assignment
-                                  statements to set the initial values.  Turn 
the result
-                                  into a local variable declaration followed 
by the
-                                  assignment statements */
-                               if($2.init)
-                               {
-                                       $$ = ILNode_Compound_CreateFrom
-                                                       
(ILNode_LocalVarDeclaration_create($1, $2.decl),
-                                                        $2.init);
-                               }
-                               else
-                               {
-                                       $$ = 
ILNode_LocalVarDeclaration_create($1, $2.decl);
-                               }
+                               $$ = ILNode_LocalVarDeclaration_create($1, $2);
                        }
        ;
 
 VariableDeclarators
        : VariableDeclarator                                                    
{
-                               $$.decl = ILNode_List_create();
-                               ILNode_List_Add($$.decl, $1.decl);
-                               $$.init = $1.init;
+                               $$ = $1;
                        }       
        | VariableDeclarators ',' VariableDeclarator    {
-                               ILNode_List_Add($1.decl, $3.decl);
-                               $$.decl = $1.decl;
-                               if($1.init)
+                               if(!yyisa($1, ILNode_List))
                                {
-                                       if($3.init)
-                                       {
-                                               $$.init = 
ILNode_Compound_CreateFrom($1.init, $3.init);
-                                       }
-                                       else
-                                       {
-                                               $$.init = $1.init;
-                                       }
-                               }
-                               else if($3.init)
-                               {
-                                       $$.init = $3.init;
+                                       $$ = ILNode_List_create();
+                                       ILNode_List_Add($$, $1);
                                }
                                else
                                {
-                                       $$.init = 0;
+                                       $$ = $1;
                                }
+                               ILNode_List_Add($$, $3);
                        }
        ;
 
 VariableDeclarator
-       : Identifier                                                    { 
$$.decl = $1; $$.init = 0; }
+       : Identifier                                                    { $$ = 
$1; }
        | Identifier '=' VariableInitializer    {
-                               $$.decl = $1;
-                               $$.init = ILNode_Assign_create($1, $3);
+                               MakeBinary(VariableDeclarator, $1, $3);
                        }
        ;
 
@@ -2946,16 +2918,16 @@ LockStatement
 
 UsingStatement
        : USING ResourceAcquisition EmbeddedStatement   {
-                               MakeBinary(Using, $2, $3);
+                               MakeBinary(UsingStatement, $2, $3);
                                $$ = ILNode_NewScope_create($$);
                        }
        ;
 
 ResourceAcquisition
        : '(' LocalVariableType VariableDeclarators ')' { 
-                       MakeTernary(ResourceDeclaration,$2,$3.decl,$3.init); 
+                       MakeBinary(ResourceDeclaration, $2, $3);
                }
-       | '(' Expression ')'                            { 
+       | '(' Expression ')'                            {
                        $$ = $2;
                }
        | '(' error ')'         {
diff --git a/cscc/csharp/cs_lvalue.tc b/cscc/csharp/cs_lvalue.tc
index 6ae4046..c6f734f 100644
--- a/cscc/csharp/cs_lvalue.tc
+++ b/cscc/csharp/cs_lvalue.tc
@@ -1364,9 +1364,36 @@ ILNode_SemAnalysisType(ILNode_GenericTypeConstraint)
 
 
 /*
- * Perform semantic analysis for local and argument variables.
+ * Perform semantic analysis for local variables.
+ */
+ILNode_SemAnalysis(ILNode_LocalVar)
+{
+       ILNode_MethodDeclaration *method;
+
+       /* Locate the method that this local is declared within */
+       method = (ILNode_MethodDeclaration *)(info->currentMethod);
+
+       /* Get the type of the local from the local variable signature */
+       if(method->localVarSig)
+       {
+               ILType *type;
+
+               type = ILTypeGetLocal(method->localVarSig, node->index);
+               if(type)
+               {
+                       CSSemValue value;
+
+                       CSSemSetLValue(value, type);
+                       return value;
+               }
+       }
+
+       return CSSemValueDefault;
+}
+
+/*
+ * Perform semantic analysis for argument variables.
  */
-ILNode_SemAnalysis(ILNode_LocalVar),
 ILNode_SemAnalysis(ILNode_ArgumentVar),
 ILNode_SemAnalysis(ILNode_RefArgumentVar)
 {
diff --git a/cscc/csharp/cs_modifiers.c b/cscc/csharp/cs_modifiers.c
index aeb2a85..3fc575a 100644
--- a/cscc/csharp/cs_modifiers.c
+++ b/cscc/csharp/cs_modifiers.c
@@ -101,6 +101,10 @@ static void ModifierError(char *filename, long linenum,
        {
                CCErrorOnLine(filename, linenum, msg, "volatile");
        }
+       if((modifiers & CS_MODIFIER_PARTIAL) != 0)
+       {
+               CCErrorOnLine(filename, linenum, msg, "partial");
+       }
 }
 
 /*
diff --git a/cscc/csharp/cs_stmt.tc b/cscc/csharp/cs_stmt.tc
index b0ced8e..cfe4499 100644
--- a/cscc/csharp/cs_stmt.tc
+++ b/cscc/csharp/cs_stmt.tc
@@ -152,6 +152,32 @@ static int StmtContextOK(ILGenInfo *info, int context, int 
stopContext)
        }
 }
 
+/*
+ * Add a local variable to a method.
+ * Returns the index of the new local variable in the local signature.
+ */
+static unsigned long AddLocalToMethod(ILGenInfo *info,
+                                                                         
ILNode_MethodDeclaration *method,
+                                                                         
ILType *type)
+{
+       /* Create the local variable signature for this method */
+       if(!(method->localVarSig))
+       {
+               method->localVarSig = ILTypeCreateLocalList(info->context);
+               if(!(method->localVarSig))
+               {
+                       CCOutOfMemory();
+               }
+       }
+                       
+       if(!ILTypeAddLocal(info->context, method->localVarSig, type))
+       {
+               CCOutOfMemory();
+       }
+
+       return ILTypeNumLocals(method->localVarSig) - 1;
+}
+
 static ILNode *HandleFixedExpr(ILGenInfo *info, ILNode *nameNode,
                                                           ILNode *exprNode, 
ILNode **exprParent,
                                                           int isFixAddress)
@@ -188,16 +214,6 @@ static ILNode *HandleFixedExpr(ILGenInfo *info, ILNode 
*nameNode,
                        CSSemSetValueKind(value, CSSemGetKind(value), type);
                }
 
-               /* Create the local variable signature for this method */
-               if(!(method->localVarSig))
-               {
-                       method->localVarSig = 
ILTypeCreateLocalList(info->context);
-                       if(!(method->localVarSig))
-                       {
-                               CCOutOfMemory();
-                       }
-               }
-                       
                pinnedType = ILTypeCreateRef(info->context, 
IL_TYPE_COMPLEX_PINNED,
                                                                         type);
                if(!pinnedType)
@@ -205,12 +221,7 @@ static ILNode *HandleFixedExpr(ILGenInfo *info, ILNode 
*nameNode,
                        ILGenOutOfMemory(info);
                }
 
-               if(!ILTypeAddLocal(info->context, method->localVarSig, 
pinnedType))
-               {
-                       CCOutOfMemory();
-               }
-
-               tempVar = ILTypeNumLocals(method->localVarSig) - 1;
+               tempVar = AddLocalToMethod(info, method, pinnedType);
                pinnedVar = ILNode_LocalVar_create(tempVar, 
ILTypeToMachineType(type));
 
                /* Assign the value to the pinned variable */
@@ -239,6 +250,239 @@ static ILNode *HandleFixedExpr(ILGenInfo *info, ILNode 
*nameNode,
        return expr;
 }
 
+/*
+ * Check if a type implements the IDisposable interface
+ */
+static void CheckIfDisposable(ILGenInfo *info, ILNode *node, ILType *type)
+{
+       ILType *disposableType;
+
+       disposableType=ILFindSystemType(info,"IDisposable");
+       if(!ILTypeImplements(info, type, disposableType) &&
+          !ILTypeInherits(info, type, disposableType))
+       {
+               CCErrorOnLine(yygetfilename(node), yygetlinenum(node),
+                         "`%s' does not implement 'IDisposable' interface ", 
+                         CSTypeToName(type));
+       }
+}
+
+/*
+ * Resolve the type for a local variable declaration.
+ * Returns the type on success and defaults to ILType_Int32 on error.
+ * If the type is 'var' and to be the result of the initialization statement
+ * then Null is returned.
+ */
+static ILType *FindLocalType(ILNode *node, ILGenInfo *info, ILNode **parent,
+                                                        int isUsing)
+{
+       ILType *type;
+
+#if IL_VERSION_MAJOR > 2
+       if(node && yykind(node) == yykindof(ILNode_Identifier))
+       {
+               const char *name;
+
+               name = ((ILNode_Identifier *)node)->name;
+               if(name && !strcmp(name, "var"))
+               {
+                       CSSemValue value;
+                       int save;
+
+                       save = info->inSemType;
+                       info->inSemType = info->typeGather;
+                       value = ILNode_SemAnalysisType(node, info, parent);
+                       info->inSemType = save;
+                       if(!CSSemIsType(value))
+                       {
+                               /*
+                                * This is a declaration where the type results 
from the result
+                                * type of the initialization statement.
+                                * We simply replace thy type node here and 
leave the real work
+                                * for later.
+                                */
+                               type = 0;
+                       }
+                       else
+                       {
+                               type = CSSemGetType(value);
+
+                               if(type == ILType_Void)
+                               {
+                                       CCErrorOnLine(yygetfilename(node),
+                                                                 
yygetlinenum(node),
+                                                               "`void' type is 
not allowed in this context");
+                                       type = ILType_Int32;
+                               }
+                       }
+               }
+               else
+               {
+                       /* Perform semantic analysis on the local variable type 
*/
+                       type = CSSemType(node, info, parent);
+               }
+       }
+       else
+#endif
+       {
+               /* Perform semantic analysis on the local variable type */
+               type = CSSemType(node, info, parent);
+       }
+
+       if(type && isUsing)
+       {
+               CheckIfDisposable(info, node, type);
+       }
+
+       return type;
+}
+
+/*
+ * If type is Null then the type results in the return type of the
+ * initialization expression.
+ * The resulting type of the local is returned.
+ */
+static ILType *HandleLocalDecl(ILNode *node, ILGenInfo *info, ILNode **parent,
+                                                          ILType *type, int 
isUsing)
+{
+       const char *name = 0;
+       ILNode *nameNode;
+       unsigned long varNum;
+       ILNode_MethodDeclaration *method;
+       ILType *resultType = type;
+
+       if(!node)
+       {
+               nameNode = 0;
+       }
+       if(yyisa(node, ILNode_VariableDeclarator))
+       {
+               nameNode = ((ILNode_VariableDeclarator *)node)->name;
+               parent = &(((ILNode_VariableDeclarator *)node)->name);
+       }
+       else
+       {
+               nameNode = node;
+       }
+       if(nameNode)
+       {
+               ILScopeData *data;
+
+               name = ILQualIdentName(nameNode, 0);
+               data = ILScopeLookup(info->currentScope, name, 0);
+               if(data)
+               {
+                       ILNode *errorNode;
+
+                       /* The name is already declared in this scope */
+                       CCErrorOnLine(yygetfilename(nameNode), 
yygetlinenum(nameNode),
+                                                 "`%s' is already declared in 
this scope", name);
+                       errorNode = ILScopeDataGetNode(data);
+                       if(errorNode)
+                       {
+                               CCErrorOnLine(yygetfilename(errorNode),
+                                                         
yygetlinenum(errorNode),
+                                                         "previous declaration 
here");
+                       }
+                       nameNode = 0;
+               }
+       }
+       if(!type)
+       {
+               if(node && yyisa(node, ILNode_VariableDeclarator))
+               {
+                       CSSemValue value;
+                       ILNode_VariableDeclarator *declNode;
+
+                       declNode = (ILNode_VariableDeclarator *)node;
+                       if(declNode->init)
+                       {
+                               value = ILNode_SemAnalysis(declNode->init,
+                                                                               
   info, &(declNode->init));
+
+                               if(!CSSemIsValue(value))
+                               {
+                                       CCErrorOnLine(yygetfilename(node),
+                                                                 
yygetlinenum(node),
+                                                                 "invalid 
lvalue in assignment");
+                                       if(!CSSemIsRValue(value))
+                                       {
+                                               CSSemSetRValue(value, 
ILType_Int32);
+                                       }
+                               }
+                               resultType = CSSemGetType(value);
+
+                               /* Wrap the expression to prevent double 
evaluation */
+                               declNode->init = 
ILNode_SemGuard_create(declNode->init,
+                                                                               
                                value);
+                       }
+                       else
+                       {
+                               CCErrorOnLine(yygetfilename(node),
+                                                         yygetlinenum(node),
+                                       "`var' type is not allowed without an 
initializer");
+                               resultType = ILType_Int32;
+                       }
+               }
+               else
+               {
+                       CCErrorOnLine(yygetfilename(node),
+                                                 yygetlinenum(node),
+                                       "`var' type is not allowed without an 
initializer");
+                       resultType = ILType_Int32;
+               }
+       }
+
+       /* Locate the method that this local is declared within */
+       method = (ILNode_MethodDeclaration *)(info->currentMethod);
+
+       /* Add the type to the local variable signature for this method */
+       varNum = AddLocalToMethod(info, method, resultType);
+
+       if(nameNode)
+       {
+               /* Create a local variable entry in the current scope */
+               ILScopeDeclareLocal(info->currentScope, name, varNum, nameNode);
+       }
+
+       if(isUsing)
+       {
+               /* replace the name with the local variable */
+               *parent = ILNode_LocalVar_create(varNum,
+                                                                               
 ILTypeToMachineType(resultType));
+       }
+
+       if(isUsing && node &&
+          (!yyisa(node, ILNode_VariableDeclarator) ||
+               ((ILNode_VariableDeclarator *)node)->init == 0))
+       {
+               CCErrorOnLine(yygetfilename(node),
+                                         yygetlinenum(node),
+               "resource declaration in a using statement is not allowed 
without an initializer");
+       }
+
+       return resultType;
+}
+
+static void HandleForeachVarDecl(ILNode_Foreach *node, ILGenInfo *info, ILType 
*type)
+{
+       unsigned long varNum;
+       ILNode_MethodDeclaration *method;
+
+       /* Locate the method that this local is declared within */
+       method = (ILNode_MethodDeclaration *)(info->currentMethod);
+
+       varNum = AddLocalToMethod(info, method, type);
+
+       /* Create a local variable entry in the current scope */
+       /* TODO: the variable should be marked read-only */
+       ILScopeDeclareLocal(info->currentScope, node->varName, varNum,
+                                               node->varNameNode);
+
+       node->varIndex = varNum;
+       node->varType = ILTypeToMachineType(type);
+}
+
 %}
 
 /*
@@ -359,57 +603,39 @@ ILNode_SemAnalysis(ILNode_Foreach)
 {
        CSSemValue value;
        ILScope *scope;
-       ILNode_MethodDeclaration *method;
        ILType *type;
-       /* ForeachCollection */
-       ILMethod *getEnumerator=NULL;
-       ILProperty *property=NULL;
-       ILMethod *getCurrent=NULL;
-       ILMethod *moveNext=NULL;
-       ILType *retType;
-       ILType *enumerator;
-       ILNode *castNode;
-       ILClass *arrayClass;
 
        /* Locate the scope and method for the iteration variable */
        scope = info->currentScope;
-       method = (ILNode_MethodDeclaration *)(info->currentMethod);
 
        /* Perform semantic analysis on the local variable type */
        if(CSHasUnsafeType(node->type))
        {
                CCUnsafeTypeMessage(info, (ILNode *)node);
        }
-       type = CSSemType(node->type, info, &(node->type));
+       type = FindLocalType(node->type, info, &(node->type), 0);
 
        /* Add the type to the local variable signature for this method */
-       if(!(method->localVarSig))
+       if(type)
        {
-               method->localVarSig = ILTypeCreateLocalList(info->context);
-               if(!(method->localVarSig))
-               {
-                       CCOutOfMemory();
-               }
-       }
-       if(!ILTypeAddLocal(info->context, method->localVarSig, type))
-       {
-               CCOutOfMemory();
+               HandleForeachVarDecl(node, info, type);
        }
 
-       /* Create a local variable entry in the current scope */
-       /* TODO: the variable should be marked read-only */
-       ILScopeDeclareLocal(info->currentScope, node->varName,
-                                               
ILTypeNumLocals(method->localVarSig) - 1,
-                                               node->varNameNode);
-       node->varIndex = ILTypeNumLocals(method->localVarSig) - 1;
-       node->varType = ILTypeToMachineType(type);
-
        /* Perform semantic analysis on the collection expression */
        if(!CSSemExpectValue(node->expr, info, &(node->expr), &value))
        {
                CCErrorOnLine(yygetfilename(node->expr), 
yygetlinenum(node->expr),
                                          "invalid collection expression in 
`foreach' statement");
-               node->arrayType = ILTypeCreateArray(info->context, 1, type);
+               if(type)
+               {
+                       node->arrayType = ILTypeCreateArray(info->context, 1, 
type);
+               }
+               else
+               {
+                       type = ILType_Int32;
+                       HandleForeachVarDecl(node, info, type);
+                       node->arrayType = ILTypeCreateArray(info->context, 1, 
type);
+               }
                if(!(node->arrayType))
                {
                        CCOutOfMemory();
@@ -420,36 +646,46 @@ ILNode_SemAnalysis(ILNode_Foreach)
                node->arrayType = CSSemGetType(value);
        }
 
-       /* Perform semantic analysis on the body of the "foreach" statement */
-       PushStmtContext(info, CS_STMT_LOOP);
-       StmtSem(node->stmt, info, &(node->stmt));
-       PopStmtContext(info);
-
        /* Is this a simple array-based or collection-based "foreach" 
statement? */
-       node->elemType = ILTypeGetElemType(node->arrayType);
-       if(ILType_IsSimpleArray(node->arrayType) &&
-          ILTypeIdentical(node->elemType, type))
+       if(ILType_IsSimpleArray(node->arrayType))
        {
-               /* The collection is a simple array and the iteration variable
-                  has the same type as the array elements.  We can optimise
-                  this case in the code generator to scan the array 
efficiently */
-       }
-       else if(ILType_IsSimpleArray(node->arrayType))
-       {               
-                       castNode=ILNode_EmptyExpr_create
+               /* 
+                * If the collection is a simple array and the iteration 
variable
+                * has the same type as the array elements.  We can optimise
+                * this case in the code generator to scan the array 
efficiently.
+                * Nothing has to be done here in this case.
+                */
+               node->elemType = ILTypeGetElemType(node->arrayType);
+
+               if(!type)
+               {
+                       type = node->elemType;
+                       HandleForeachVarDecl(node, info, type);
+               }
+               else if(!ILTypeIdentical(node->elemType, type))
+               {
+                       ILNode *castNode;
+
+                       castNode = ILNode_EmptyExpr_create
                                (ILTypeToMachineType(node->elemType));
-                       
if(!ILCast(info,castNode,&(castNode),node->elemType,type,1))
+                       if(!ILCast(info, castNode, &(castNode), node->elemType, 
type, 1))
                        {
                                CCErrorOnLine(yygetfilename(node), 
yygetlinenum(node),
                                        "Cannot cast '%s' to 
'%s'",CSTypeToName(node->elemType),
                                        CSTypeToName(type));
                        }
-                       node->doCast=castNode;
+                       node->doCast = castNode;
+               }
        }
        else if(ILTypeIsStringClass(node->arrayType) &&
-               ILTypeIdentical(type, ILType_Char))
+                       (!type || ILTypeIdentical(type, ILType_Char)))
        {
                /* The collection is a string, which we can special-case */
+               if(!type)
+               {
+                       type = ILType_Char;
+                       HandleForeachVarDecl(node, info, type);
+               }
                *parent = ILNode_ForeachString_create(node->expr,
                                                                                
          node->stmt,
                                                                                
          node->varIndex,
@@ -457,7 +693,14 @@ ILNode_SemAnalysis(ILNode_Foreach)
        }
        else 
        {
+               ILMethod *getEnumerator = NULL;
+               ILType *ienumerableType;
+               ILClass *arrayClass;
+
                arrayClass = ILTypeToClass(info, node->arrayType);
+               ienumerableType = ILFindNonSystemType(info,
+                                                                               
          "IEnumerable",
+                                                                               
          "System.Collections");
                if(arrayClass)
                {
                        getEnumerator = ILResolveInstanceMethod(info, 
arrayClass,
@@ -465,13 +708,12 @@ ILNode_SemAnalysis(ILNode_Foreach)
                                                                                
                        "GetEnumerator",
                                                                                
                        NULL, 0);
                }
-               if(getEnumerator==NULL &&
-                       ILTypeImplements(info, node->arrayType,
-                       
ILFindNonSystemType(info,"IEnumerable","System.Collections")))
+               if(getEnumerator == NULL &&
+                  ILTypeImplements(info, node->arrayType, ienumerableType))
                {
-                       ILClass * enumerable = ILTypeToClass(info,
-                                                                       
ILFindNonSystemType(info,"IEnumerable",
-                                                                               
                        "System.Collections"));
+                       ILClass * enumerable;
+
+                       enumerable = ILTypeToClass(info, ienumerableType);
                        enumerable = ILClassResolve(enumerable);
 
                        getEnumerator = ILResolveInstanceMethod(info, 
enumerable,
@@ -481,18 +723,24 @@ ILNode_SemAnalysis(ILNode_Foreach)
                }       
                if(getEnumerator)
                {
-                       
enumerator=ILTypeGetReturn(ILMethod_Signature(getEnumerator));
-                       property=ILResolveProperty(info,
-                                                       
ILType_ToClass(enumerator),
-                                                       GetDefaultScope(info),
-                                                       "Current");
-                       
-                       getCurrent=(property ? ILProperty_Getter(property) : 0);
+                       ILProperty *property = NULL;
+                       ILMethod *getCurrent = NULL;
+                       ILMethod *moveNext = NULL;
+                       ILType *retType;
+                       ILType *enumerator;
+
+                       enumerator = 
ILTypeGetReturn(ILMethod_Signature(getEnumerator));
+                       property = ILResolveProperty(info,
+                                                                               
 ILType_ToClass(enumerator),
+                                                                               
 GetDefaultScope(info),
+                                                                               
 "Current");
 
-                       moveNext=ILResolveInstanceMethod(info,
-                                               ILType_ToClass(enumerator),
-                                               GetDefaultScope(info),
-                                               "MoveNext",     NULL, 0);
+                       getCurrent = (property ? ILProperty_Getter(property) : 
0);
+
+                       moveNext = ILResolveInstanceMethod(info,
+                                                                               
           ILType_ToClass(enumerator),
+                                                                               
           GetDefaultScope(info),
+                                                                               
           "MoveNext", NULL, 0);
 
                        if(!property) 
                        {
@@ -503,8 +751,8 @@ ILNode_SemAnalysis(ILNode_Foreach)
                        else if(!getCurrent)
                        {
                                CCErrorOnLine(yygetfilename(node), 
yygetlinenum(node),
-                               "'Current' property has no 'get' method in 
'%s'",
-                                         CSTypeToName(enumerator));
+                                                         "'Current' property 
has no 'get' method in '%s'",
+                                                         
CSTypeToName(enumerator));
                        }
                        if(!moveNext) 
                        {
@@ -512,58 +760,79 @@ ILNode_SemAnalysis(ILNode_Foreach)
                          "Cannot locate 'MoveNext()' or 
'IEnumerator.MoveNext()' in '%s'",
                                          CSTypeToName(enumerator));
                        }
-                       if(!getCurrent || !moveNext)
+                       if(getCurrent && moveNext)
                        {
-                               /* Bail out if we have insufficient interface 
support */
-                               return CSSemValueDefault;
-                       }
-                       
-                       retType=ILTypeGetReturn(ILMethod_Signature(getCurrent));
-
-                       if(ILTypeIdentical(type,retType))       
-                       {       
-                               *parent=ILNode_ForeachCollection_create(
-                                               NULL,
-                                               node->expr,
-                                               node->stmt,
-                                               node->arrayType,
-                                               node->varIndex,
-                                               ILTypeToMachineType(type),
-                                               enumerator,
-                                               getEnumerator,
-                                               moveNext,
-                                               getCurrent);
-                       }
-                       else
-                       {       
-                               
castNode=ILNode_EmptyExpr_create(ILTypeToMachineType(retType));
-                               
if(!ILCast(info,castNode,&(castNode),retType,type,1))
+                               retType = 
ILTypeGetReturn(ILMethod_Signature(getCurrent));
+
+                               if(!type)
+                               {
+                                       type = retType;
+                                       HandleForeachVarDecl(node, info, type);
+                                       *parent = 
ILNode_ForeachCollection_create(
+                                                               NULL,
+                                                               node->expr,
+                                                               node->stmt,
+                                                               node->arrayType,
+                                                               node->varIndex,
+                                                               
ILTypeToMachineType(type),
+                                                               enumerator,
+                                                               getEnumerator,
+                                                               moveNext,
+                                                               getCurrent);
+                               }
+                               else if(ILTypeIdentical(type, retType)) 
+                               {       
+                                       *parent = 
ILNode_ForeachCollection_create(
+                                                               NULL,
+                                                               node->expr,
+                                                               node->stmt,
+                                                               node->arrayType,
+                                                               node->varIndex,
+                                                               
ILTypeToMachineType(type),
+                                                               enumerator,
+                                                               getEnumerator,
+                                                               moveNext,
+                                                               getCurrent);
+                               }
+                               else
                                {
-                                       CCErrorOnLine(yygetfilename(node), 
yygetlinenum(node),
-                                               "Cannot cast '%s' to 
'%s'",CSTypeToName(retType),
-                                               CSTypeToName(type));
+                                       ILNode *castNode;
+
+                                       castNode = 
ILNode_EmptyExpr_create(ILTypeToMachineType(retType));
+                                       if(!ILCast(info, castNode, &(castNode), 
retType, type, 1))
+                                       {
+                                               
CCErrorOnLine(yygetfilename(node), yygetlinenum(node),
+                                                       "Cannot cast '%s' to 
'%s'",CSTypeToName(retType),
+                                                       CSTypeToName(type));
+                                       }
+                                       *parent = 
ILNode_ForeachCollection_create(
+                                                               castNode,
+                                                               node->expr,
+                                                               node->stmt,
+                                                               node->arrayType,
+                                                               node->varIndex,
+                                                               
ILTypeToMachineType(type),
+                                                               enumerator,
+                                                               getEnumerator,
+                                                               moveNext,
+                                                               getCurrent);
                                }
-                               *parent=ILNode_ForeachCollection_create(
-                                               castNode,
-                                               node->expr,
-                                               node->stmt,
-                                               node->arrayType,
-                                               node->varIndex,
-                                               ILTypeToMachineType(type),
-                                               enumerator,
-                                               getEnumerator,
-                                               moveNext,
-                                               getCurrent);
                        }
                }
                else
                {
                        CCErrorOnLine(yygetfilename(node), yygetlinenum(node),
                         "Could not locate a 'GetEnumerator' or "
-                        "'IEnumerable.GetEnumerator' in '%s'"
-                        ,CSTypeToName(node->arrayType));
+                        "'IEnumerable.GetEnumerator' in '%s'",
+                        CSTypeToName(node->arrayType));
                }
        }
+
+       /* Perform semantic analysis on the body of the "foreach" statement */
+       PushStmtContext(info, CS_STMT_LOOP);
+       StmtSem(node->stmt, info, &(node->stmt));
+       PopStmtContext(info);
+
        /* Done */
        return CSSemValueDefault;
 }
@@ -1404,27 +1673,16 @@ ILNode_SemAnalysis(ILNode_CatchClause)
        /* Declare a new local variable for the catch value */
        if(node->name)
        {
+               unsigned long varNum;
+
                /* Add the type to the local variable signature for this method 
*/
-               if(!(method->localVarSig))
-               {
-                       method->localVarSig = 
ILTypeCreateLocalList(info->context);
-                       if(!(method->localVarSig))
-                       {
-                               CCOutOfMemory();
-                       }
-               }
-               if(!ILTypeAddLocal(info->context, method->localVarSig, 
thrownType))
-               {
-                       CCOutOfMemory();
-               }
+               varNum = AddLocalToMethod(info, method, thrownType);
 
                /* Create a local variable entry in the current scope */
-               ILScopeDeclareLocal(newScope, node->name,
-                                                       
ILTypeNumLocals(method->localVarSig) - 1,
-                                                       node->nameNode);
+               ILScopeDeclareLocal(newScope, node->name, varNum, 
node->nameNode);
 
                /* Record the local variable index for the code generator */
-               node->varIndex = ILTypeNumLocals(method->localVarSig) - 1;
+               node->varIndex = varNum;
        }
 
        /* Perform semantic analysis on the catch body */
@@ -1497,124 +1755,252 @@ ILNode_SemAnalysis(ILNode_Lock)
 /*
  * Perform semantic analysis for the "using" statement.
  */
-ILNode_SemAnalysis(ILNode_Using)
+ILNode_SemAnalysis(ILNode_UsingStatement)
 {
-       CSSemValue value;
-       ILType *type;
-       ILType *disposable;
+       ILNode **stmtParent = 0;
        
-       if(yyisa(node->resource,ILNode_ResourceDeclaration))
+       if(yyisa(node->resource, ILNode_ResourceDeclaration))
        {
-               /* TODO: Handle the declaration of multiple resources in the
-                  using statement like using(type a, b, c) { ... }.
-                  They should be converted to distinct nested using statements
-                  like using(type a) { using(type b) { using(type c) { ... 
}}}. */
-               ILNode_SemAnalysis(node->resource,info,&(node->resource));
+               ILType *type;
+               ILNode_ResourceDeclaration *resource;
+
+               resource = (ILNode_ResourceDeclaration *)(node->resource);
+
+               /* Perform semantic analysis on the resource variable type */
+               type = FindLocalType(resource->type, info, &(resource->type), 
1);
+
+               if(yyisa(resource->variables, ILNode_List))
+               {
+                       ILNode *varNode;
+                       ILNode_ListIter iter;
+
+                       /* Scan through the variable names and declare them in 
the current scope */
+                       ILNode_ListIter_Init(&iter, resource->variables);
+                       while((varNode = ILNode_ListIter_Next(&iter)) != 0)
+                       {
+                               ILNode *initNode;
+                               ILType *newType;
+
+                               initNode = varNode;
+                               newType = HandleLocalDecl(initNode, info, 
&initNode, type, 1);
+
+                               if(yyisa(initNode, ILNode_VariableDeclarator))
+                               {
+                                       ILNode_VariableDeclarator *declNode;
+                                       ILNode_LocalVar *localNode;
+                                       ILNode_Using *using;
+
+                                       declNode = (ILNode_VariableDeclarator 
*)(initNode);
+                                       localNode = (ILNode_LocalVar 
*)(declNode->name);
+
+                                       StmtSem(initNode, info, &initNode);
+
+                                       if(stmtParent)
+                                       {
+                                               using = (ILNode_Using 
*)ILNode_Using_create(localNode,
+                                                                               
                                                        initNode,
+                                                                               
                                                        *stmtParent,
+                                                                               
                                                        newType);
+                                               *stmtParent = (ILNode *)using;
+                                       }
+                                       else
+                                       {
+                                               using = (ILNode_Using 
*)ILNode_Using_create(localNode,
+                                                                               
                                                        initNode,
+                                                                               
                                                        node->stmt,
+                                                                               
                                                        newType);
+
+                                               node->resource = (ILNode 
*)using;
+                                       }
+                                       stmtParent = &(using->stmt);
+                               }
+                               else
+                               {
+                                       /* In using statements the variables 
shall have an initializer */
+                                       stmtParent = 0;
+                               }
+                       }
+               }
+               else
+               {
+                       ILType *newType;
+
+                       newType = HandleLocalDecl(resource->variables, info,
+                                                                         
&(resource->variables), type, 1);
+
+                       if(yyisa(resource->variables, 
ILNode_VariableDeclarator))
+                       {
+                               ILNode_VariableDeclarator *declNode;
+                               ILNode *initNode;
+                               ILNode_LocalVar *varNode;
+                               ILNode_Using *using;
+
+                               declNode = (ILNode_VariableDeclarator 
*)(resource->variables);
+                               initNode = resource->variables;
+                               varNode = (ILNode_LocalVar *)(declNode->name);
+
+                               StmtSem(initNode, info, &(initNode));
+
+                               using = (ILNode_Using 
*)ILNode_Using_create(varNode,
+                                                                               
                                        initNode,
+                                                                               
                                        node->stmt,
+                                                                               
                                        newType);
+
+                               stmtParent = &(using->stmt);
+                               node->resource = (ILNode *)using;
+                       }
+                       else
+                       {
+                               /* In using statements the variables shall have 
an initializer */
+                               stmtParent = 0;
+                       }
+               }
        }
        else 
        {
-               
value=ILNode_SemAnalysis(node->resource,info,&(node->resource));                
-               if(!CSSemGetType(value))
+               ILType *type;
+               CSSemValue value;
+
+               value = ILNode_SemAnalysis(node->resource, info, 
&(node->resource));
+               type = CSSemGetType(value);
+               if(!type)
                {
-                       CCErrorOnLine(yygetfilename(node->resource), 
-                               yygetlinenum(node->resource), 
-                               "invalid expression");
+                       CCErrorOnLine(yygetfilename(node->resource),
+                                                 yygetlinenum(node->resource),
+                                                 "invalid expression");
+                       stmtParent = 0;
                }
-               disposable=ILFindSystemType(info,"IDisposable");
-               type=CSSemGetType(value);
-               if(!ILTypeImplements(info,type,disposable) && 
-                       !ILTypeImplements(info,type,disposable))
+               else
                {
-                       CCErrorOnLine(yygetfilename(node->resource), 
-                               yygetlinenum(node->resource), 
-                               "'%s' does not implement 'IDisposable'",
-                                       CSTypeToName(type));
+                       unsigned long varNum;
+                       ILNode_MethodDeclaration *method;
+                       ILNode_LocalVar *varNode;
+                       ILNode *initNode;
+                       ILNode_Using *using;
+
+                       CheckIfDisposable(info, node->resource, type);
+
+                       /* Locate the method that this local is declared within 
*/
+                       method = (ILNode_MethodDeclaration 
*)(info->currentMethod);
+
+                       /* Add the type to the local variable signature for 
this method */
+                       varNum = AddLocalToMethod(info, method, type);
+
+                       /* create a nameless local variable */
+                       varNode = (ILNode_LocalVar 
*)ILNode_LocalVar_create(varNum,
+                                                                               
         ILTypeToMachineType(type));
+
+                       initNode = ILNode_SemGuard_create(node->resource, 
value);
+                       initNode = ILNode_Assign_create((ILNode *)varNode, 
initNode);
+
+                       /* Perform semantic analysis on the initializer */
+                       ILNode_SemAnalysis(initNode, info, &initNode);
+
+                       using = (ILNode_Using *)ILNode_Using_create(varNode,
+                                                                               
                                initNode,
+                                                                               
                                node->stmt,
+                                                                               
                                type);
+
+                       stmtParent = &(using->stmt);
+                       node->resource = (ILNode *)using;
                }
        }
-       ILNode_SemAnalysis(node->stmt,info,&(node->stmt));
+
+       /* Now perform the semantic analysis on the statement itself */
+       if(stmtParent)
+       {
+               ILNode_SemAnalysis(*stmtParent, info, stmtParent);
+       }
+       else
+       {
+               ILNode_SemAnalysis(node->stmt, info, &(node->stmt));
+       }
+
        return CSSemValueDefault;
 }
 
 /*
  * Generate discard code for the "using" statement.
  */
+ILNode_GenDiscard(ILNode_UsingStatement)
+{
+       ILNode_GenDiscard(node->resource, info);
+}
+
+/*
+ * Perform semantic analysis for a "using" node.
+ */
+ILNode_SemAnalysis(ILNode_Using)
+{
+       return CSSemValueDefault;
+}
+
+/*
+ * Generate discard code for the "using" node.
+ */
 ILNode_GenDiscard(ILNode_Using)
 {
-       ILNode *vars;
-       ILNode_ListIter iter;
-       ILNode_LocalVar *varNode;
-       unsigned tempVar=0;
-       
+       ILLabel label = ILLabel_Undefined;
        ILLabel label1 = ILLabel_Undefined;
-       ILLabel label2 = ILLabel_Undefined;
-       if(yyisa(node->resource,ILNode_ResourceDeclaration))
-       {
-               ILNode_GenDiscard(node->resource,info);
-       }
-       else
-       {
-               
tempVar=ILGenTempTypedVar(info,ILFindSystemType(info,"IDisposable"));
-               ILNode_GenValue(node->resource,info);
-               ILGenStoreLocal(info,tempVar);  
-               ILGenAdjust(info,-1);
-       }
-       
-       /* Encapsulate the loop in a "try" block so that the "Dispose"
+
+       /* First run the initializer for the local */
+       ILNode_GenDiscard(node->init, info);
+
+       /* Encapsulate the statement in a "try" block so that the "Dispose"
           method can be called in finally */
        if(info->asmOutput)
        {
                fputs("\t.try {\n", info->asmOutput);
        }
        ILGenPushTry(info);
-       ILNode_GenDiscard(node->stmt,info);
-       ILGenJump(info, IL_OP_LEAVE, &label1);
+
+       /* Generate the dicard code for the statement */
+       ILNode_GenDiscard(node->stmt, info);
+
+       /* Leave the try block */
+       ILGenJump(info, IL_OP_LEAVE, &label);
+       
+       /* end the try block and start a finally block */
        ILGenPopTry(info);
        if(info->asmOutput)
        {
                fputs("\t} finally {\n", info->asmOutput);
        }
-       if(yyisa(node->resource,ILNode_ResourceDeclaration))
-       {
-               vars=((ILNode_ResourceDeclaration*)(node->resource))->variables;
-               ILNode_ListIter_Init(&iter, vars);
-               while((varNode = (ILNode_LocalVar*)ILNode_ListIter_Next(&iter)) 
!= 0)
-               {
-                       ILGenLoadLocal(info, varNode->index);
-                       ILGenAdjust(info, 1);
-                       ILGenJump(info, IL_OP_BRFALSE, &label2);
-                       ILGenAdjust(info,-1);
-                       ILGenLoadLocal(info, varNode->index);
-                       ILGenAdjust(info, 1);
-                       ILGenCallVirtual(info, 
+
+       /* Generate the dispose code */
+       /* TODO: handle value types */
+       ILGenLoadLocal(info, node->localVar->index);
+       ILGenAdjust(info, 1);
+       ILGenJump(info, IL_OP_BRFALSE, &label1);
+       ILGenAdjust(info,-1);
+       ILGenLoadLocal(info, node->localVar->index);
+       ILGenAdjust(info, 1);
+       ILGenCallVirtual(info, 
                                "void [.library]System.IDisposable::Dispose()");
-                       ILGenAdjust(info, -1);
-               }
-       }
-       else
-       {
-               ILGenLoadLocal(info, tempVar);
-               ILGenAdjust(info, 1);
-               ILGenJump(info, IL_OP_BRFALSE, &label2);
-               ILGenAdjust(info,-1);
-               ILGenLoadLocal(info, tempVar);
-               ILGenAdjust(info, 1);
-               ILGenCallVirtual(info, 
-                       "void [.library]System.IDisposable::Dispose()");
-               ILGenAdjust(info, -1);
-               ILGenReleaseTempVar(info,tempVar);
-       }
+       ILGenAdjust(info, -1);
+
+       /* Leave the finally block */
+       ILGenLabel(info, &label1);
        ILGenSimple(info, IL_OP_ENDFINALLY);
-       ILGenLabel(info,&label2);
        if(info->asmOutput)
        {
                fputs("\t}\n",info->asmOutput);
        }
-       ILGenLabel(info,&label1);
+
+       ILGenLabel(info, &label);
 }
 
 /*
  * Generate Java discard code for the "using" statement.
  */
+JavaGenDiscard(ILNode_UsingStatement)
+{
+       JavaGenDiscard(node->resource, info);
+}
+
+/*
+ * Generate Java discard code for the "using" node.
+ */
 JavaGenDiscard(ILNode_Using)
 {
        /* TODO */
@@ -1623,7 +2009,7 @@ JavaGenDiscard(ILNode_Using)
 /*
  * Determine if a "using" statement ends in a return statement.
  */
-ILNode_EndsInReturnImpl(ILNode_Using)
+ILNode_EndsInReturnImpl(ILNode_UsingStatement)
 {
        return ILNode_EndsInReturnImpl(node->stmt,info);
 }
@@ -1719,29 +2105,18 @@ ILNode_SemAnalysis(ILNode_Fixed)
                }
                else
                {
-                       /* Add the type to the local variable signature for 
this method */
-                       if(!(method->localVarSig))
-                       {
-                               method->localVarSig = 
ILTypeCreateLocalList(info->context);
-                               if(!(method->localVarSig))
-                               {
-                                       CCOutOfMemory();
-                               }
-                       }
-                       
+                       unsigned long varNum;
+
                        if(yyisa(varNode,ILNode_FixAddress))
                        {
                                /* TODO : figure the right way to pin variables 
*/
                        }
                        
-                       if(!ILTypeAddLocal(info->context, method->localVarSig, 
type))
-                       {
-                               CCOutOfMemory();
-                       }
-
+                       /* Add the type to the local variable signature for 
this method */
+                       varNum = AddLocalToMethod(info, method, type);
+                       
                        /* Create a local variable entry in the current scope */
-                       ILScopeDeclareLocal(info->currentScope, name,
-                                                               
ILTypeNumLocals(method->localVarSig) - 1,
+                       ILScopeDeclareLocal(info->currentScope, name, varNum,
                                                                
((ILNode_FixedVariable*)varNode)->name);
                        info->inFixed = -1;
                        ILNode_SemAnalysis(varNode,info,iter.last);
@@ -1803,62 +2178,67 @@ ILNode_SemAnalysis(ILNode_FixExpr)
 }
 
 /*
+ * Perform semantic analysis for a variable declaration.
+ */
+ILNode_SemAnalysis(ILNode_VariableDeclarator)
+{
+       if(node->init)
+       {
+               /*
+                * if we have an initializer then replace this node by an 
assignment
+                */
+               *parent = ILNode_Assign_create(node->name, node->init);
+
+               /*
+                * and perform semantic analysis on the assignment node.
+                */
+               return ILNode_SemAnalysis(*parent, info, parent);
+       }
+
+       /* Return the default value to the caller */
+       return CSSemValueDefault;
+}
+
+/*
  * Perform semantic analysis for local variable declarations.
  */
 ILNode_SemAnalysis(ILNode_LocalVarDeclaration)
 {
        ILType *type;
-       ILNode_ListIter iter;
-       ILNode *nameNode;
-       const char *name;
-       ILScopeData *data;
-       ILNode_MethodDeclaration *method;
-       ILNode *errorNode;
 
-       /* Locate the method that this local is declared within */
-       method = (ILNode_MethodDeclaration *)(info->currentMethod);
+       type = FindLocalType(node->type, info, &(node->type), 0);
 
-       /* Perform semantic analysis on the local variable type */
-       type = CSSemType(node->type, info, &(node->type));
-
-       /* Scan through the variable names and declare them in the current 
scope */
-       ILNode_ListIter_Init(&iter, node->varNames);
-       while((nameNode = ILNode_ListIter_Next(&iter)) != 0)
+       if(yyisa(node->varNames, ILNode_List))
        {
-               name = ILQualIdentName(nameNode, 0);
-               data = ILScopeLookup(info->currentScope, name, 0);
-               if(data)
-               {
-                       /* The name is already declared in this scope */
-                       CCErrorOnLine(yygetfilename(nameNode), 
yygetlinenum(nameNode),
-                                                 "`%s' is already declared in 
this scope", name);
-                       errorNode = ILScopeDataGetNode(data);
-                       if(errorNode)
-                       {
-                               CCErrorOnLine(yygetfilename(errorNode), 
yygetlinenum(errorNode),
-                                                         "previous declaration 
here");
-                       }
-               }
-               else
+               ILNode *varNode;
+               ILNode_ListIter iter;
+
+               /* Scan through the variable names and declare them in the 
current scope */
+               ILNode_ListIter_Init(&iter, node->varNames);
+               while((varNode = ILNode_ListIter_Next(&iter)) != 0)
                {
-                       /* Add the type to the local variable signature for 
this method */
-                       if(!(method->localVarSig))
+                       ILNode *replace;
+
+                       replace = varNode;
+                       HandleLocalDecl(varNode, info, &replace, type, 0);
+
+                       if(yyisa(replace, ILNode_VariableDeclarator))
                        {
-                               method->localVarSig = 
ILTypeCreateLocalList(info->context);
-                               if(!(method->localVarSig))
-                               {
-                                       CCOutOfMemory();
-                               }
+                               StmtSem(replace, info, &replace);
                        }
-                       if(!ILTypeAddLocal(info->context, method->localVarSig, 
type))
+                       if(replace != varNode)
                        {
-                               CCOutOfMemory();
+                               *(iter.last) = replace;
                        }
+               }
+       }
+       else
+       {
+               HandleLocalDecl(node->varNames, info, &(node->varNames), type, 
0);
 
-                       /* Create a local variable entry in the current scope */
-                       ILScopeDeclareLocal(info->currentScope, name,
-                                                               
ILTypeNumLocals(method->localVarSig) - 1,
-                                                               nameNode);
+               if(yyisa(node->varNames, ILNode_VariableDeclarator))
+               {
+                       StmtSem(node->varNames, info, &(node->varNames));
                }
        }
 
@@ -1887,7 +2267,7 @@ ILNode_SemAnalysis(ILNode_LocalConstDeclaration)
 
        /* Perform semantic analysis on the local variable type */
        type = CSSemType(node->type, info, &(node->type));
-               
+
        ILNode_ListIter_Init(&iterator, node->decls);
        while((decl = (ILNode_FieldDeclarator *)
                                                
ILNode_ListIter_Next(&iterator)) != 0)
@@ -2004,87 +2384,17 @@ ILNode_SemAnalysis(ILNode_Memset)
 }
 
 /*
- * This is ILNode_LocalVarDeclaration's copy ,except for the fact that
- * all nodes are replaced with ILNode_LocVar after SemAnalysis.
+ * Perform semantic analysis for a resource declaration.
  */
 ILNode_SemAnalysis(ILNode_ResourceDeclaration)
 {
-       ILType *type;
-       ILNode_ListIter iter;
-       ILNode *nameNode;
-       const char *name;
-       ILScopeData *data;
-       ILNode_MethodDeclaration *method;
-       ILNode *errorNode;
-       ILType *disposableType;
-       /* Locate the method that this local is declared within */
-       method = (ILNode_MethodDeclaration *)(info->currentMethod);
-
-       /* Perform semantic analysis on the local variable type */
-       type = CSSemType(node->type, info, &(node->type));
-
-       disposableType=ILFindSystemType(info,"IDisposable");
-       if(! ILTypeImplements(info,type,disposableType) 
-               && !ILTypeInherits(info,type,disposableType))
-       {
-               CCErrorOnLine(yygetfilename(node->type), 
yygetlinenum(node->type),
-                         "`%s' does not implement 'IDisposable' interface ", 
-                         CSTypeToName(type));
-       }
-
-       /* Scan through the variable names and declare them in the current 
scope */
-       ILNode_ListIter_Init(&iter, node->variables);
-       while((nameNode = ILNode_ListIter_Next(&iter)) != 0)
-       {
-               name = ILQualIdentName(nameNode, 0);
-               data = ILScopeLookup(info->currentScope, name, 0);
-               if(data)
-               {
-                       /* The name is already declared in this scope */
-                       CCErrorOnLine(yygetfilename(nameNode), 
yygetlinenum(nameNode),
-                                                 "`%s' is already declared in 
this scope", name);
-                       errorNode = ILScopeDataGetNode(data);
-                       if(errorNode)
-                       {
-                               CCErrorOnLine(yygetfilename(errorNode), 
yygetlinenum(errorNode),
-                                                         "previous declaration 
here");
-                       }
-               }
-               else
-               {
-                       /* Add the type to the local variable signature for 
this method */
-                       if(!(method->localVarSig))
-                       {
-                               method->localVarSig = 
ILTypeCreateLocalList(info->context);
-                               if(!(method->localVarSig))
-                               {
-                                       CCOutOfMemory();
-                               }
-                       }
-                       if(!ILTypeAddLocal(info->context, method->localVarSig, 
type))
-                       {
-                               CCOutOfMemory();
-                       }
-
-                       /* Create a local variable entry in the current scope */
-                       ILScopeDeclareLocal(info->currentScope, name,
-                                                               
ILTypeNumLocals(method->localVarSig) - 1,
-                                                               nameNode);
-
-                       /* replace the name with the local variable */
-                       *(iter.last) = ILNode_LocalVar_create(
-                                                       
ILTypeNumLocals(method->localVarSig)-1,
-                                                       
ILTypeToMachineType(type));
-               }
-       }
-
-       ILNode_SemAnalysis(node->init,info, &(node->init));
-
-       /* Return the default value to the caller */
+       /*
+        * This is handled completely in semanalyzing an ILNode_UsingStatement.
+        */
        return CSSemValueDefault;
 }
 
 ILNode_GenDiscard(ILNode_ResourceDeclaration)
 {
-       ILNode_GenDiscard(node->init,info);
+       ILNode_GenDiscard(node->variables, info);
 }

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                  |   57 +++
 codegen/cg_nodes.tc        |    5 +
 codegen/cg_stmt.tc         |   14 +-
 codegen/jv_stmt.tc         |   15 +-
 cscc/c/c_stubs.tc          |    1 +
 cscc/csharp/cs_defs.tc     |   13 +-
 cscc/csharp/cs_gather.c    |    2 +-
 cscc/csharp/cs_grammar.y   |   54 +--
 cscc/csharp/cs_lvalue.tc   |   31 ++-
 cscc/csharp/cs_modifiers.c |    4 +
 cscc/csharp/cs_stmt.tc     | 1016 +++++++++++++++++++++++++++++---------------
 11 files changed, 809 insertions(+), 403 deletions(-)


hooks/post-receive
-- 
DotGNU Portable.NET engine, compilers and tools (pnet)




reply via email to

[Prev in Thread] Current Thread [Next in Thread]