From 51c3b0cb84ed625b6f25fa6d159c6eea2724c283 Mon Sep 17 00:00:00 2001 From: Miguel de Icaza Date: Mon, 28 Jan 2002 14:03:27 +0000 Subject: 2002-01-28 Miguel de Icaza * support.cs: Api for Pair to set a value. Despite the fact that the variables are public the MS C# compiler refuses to compile code that accesses the field if the variable is part of a foreach statement. * statement.cs (Fixed): Begin implementation of the fixed statement. (Block.AddVariable): Return the VariableInfo on success and null on failure instead of true/false. * cs-parser.jay (foreach): Catch errors on variables already defined (we were ignoring this value before) and properly unwind the block hierarchy (fixed_statement): grammar for the fixed statement. svn path=/trunk/mcs/; revision=2183 --- mcs/errors/cs0214.cs | 23 +++---------- mcs/mcs/ChangeLog | 19 +++++++++++ mcs/mcs/cs-parser.jay | 90 +++++++++++++++++++++++++++++++++++++++------------ mcs/mcs/statement.cs | 48 ++++++++++++++++++++++++--- mcs/mcs/support.cs | 13 +++++--- 5 files changed, 144 insertions(+), 49 deletions(-) diff --git a/mcs/errors/cs0214.cs b/mcs/errors/cs0214.cs index e71b5f53af4..08eb088af39 100644 --- a/mcs/errors/cs0214.cs +++ b/mcs/errors/cs0214.cs @@ -1,20 +1,5 @@ -// cs0214.cs : Pointers may only be used in an unsafe context -// Line : 14 - -using System; -using System.Reflection; - -public class Blah { - - public static void Main () - { - int* i; - int foo = 10; - - i = &foo; - - Console.WriteLine ("The pointer value is " + i); - } +// cs0214: Pointer can only be used in unsafe context +// Line: 4 +class X { + void *a; } - - diff --git a/mcs/mcs/ChangeLog b/mcs/mcs/ChangeLog index 3d6e1873a3b..62975d41a83 100755 --- a/mcs/mcs/ChangeLog +++ b/mcs/mcs/ChangeLog @@ -1,3 +1,22 @@ +2002-01-28 Miguel de Icaza + + * support.cs: Api for Pair to set a value. Despite the fact that + the variables are public the MS C# compiler refuses to compile + code that accesses the field if the variable is part of a foreach + statement. + + * statement.cs (Fixed): Begin implementation of the fixed + statement. + + (Block.AddVariable): Return the VariableInfo on success and null + on failure instead of true/false. + + * cs-parser.jay (foreach): Catch errors on variables already + defined (we were ignoring this value before) and properly unwind + the block hierarchy + + (fixed_statement): grammar for the fixed statement. + 2002-01-25 Miguel de Icaza * expression.cs (UnaryMutator.IsIncrementableNumber): Allow also diff --git a/mcs/mcs/cs-parser.jay b/mcs/mcs/cs-parser.jay index 67d928a6634..b6605e7dbe7 100755 --- a/mcs/mcs/cs-parser.jay +++ b/mcs/mcs/cs-parser.jay @@ -2959,13 +2959,15 @@ for_statement foreach (VariableDeclaration decl in var_declarators){ - if (!current_block.AddVariable (type, decl.identifier, current_local_parameters, - decl.Location)) { + VariableInfo vi; + + vi = current_block.AddVariable ( + type, decl.identifier, current_local_parameters, decl.Location); + if (vi == null){ Report.Error (128, decl.Location, - "A local variable `" + decl.identifier + "' is already" + - "defined in this scope"); + "A local variable `" + decl.identifier + + "' is already defined in this scope"); } else { - Location l = lexer.Location; Expression expr; if (decl.expression_or_array_initializer is Expression){ @@ -3061,25 +3063,36 @@ foreach_statement } expression CLOSE_PARENS { + oob_stack.Push (current_block); + Block foreach_block = new Block (current_block, true); LocalVariableReference v; Location l = lexer.Location; + VariableInfo vi; + + vi = foreach_block.AddVariable ((string) $3, (string) $4, current_local_parameters, l); + if (vi == null){ + Report.Error ( + 128, l, "A local variable `" + (string) $4 + "' is already "+ + "defined in this scope"); + } - foreach_block.AddVariable ((string) $3, (string) $4, current_local_parameters, l); v = new LocalVariableReference (foreach_block, (string) $4, l); current_block.AddStatement (foreach_block); current_block = foreach_block; - oob_stack.Push (foreach_block); oob_stack.Push (v); } embedded_statement { LocalVariableReference v = (LocalVariableReference) oob_stack.Pop (); - Block foreach_block = (Block) oob_stack.Pop (); + Block prev_block = (Block) oob_stack.Pop (); Location l = (Location) oob_stack.Pop (); + while (current_block != prev_block) + current_block = current_block.Parent; + $$ = new Foreach ((string) $3, v, (Expression) $7, (Statement) $10, l); } ; @@ -3288,25 +3301,59 @@ unsafe_statement fixed_statement : FIXED OPEN_PARENS - // FIXME: pointer_type fixed_pointer_declarators - CLOSE_PARENS embedded_statement + pointer_type fixed_pointer_declarators + CLOSE_PARENS + { + Block assign_block = new Block (current_block, true); + + string type = (string) $3; + Location l = lexer.Location; + + foreach (Pair p in (ArrayList) $4){ + VariableInfo v; + + v = current_block.AddVariable (type, (string) p.First,current_local_parameters, l); + if (v == null){ + Report.Error ( + 128, l, "A local variable `" + (string) p.First + "' is already "+ + "defined in this scope"); + } + v.ReadOnly = true; + // Replace the name with the VariableInfo. + p.SetFirst (v); + } + current_block.AddStatement (assign_block); + current_block = assign_block; + oob_stack.Push (l); + } + embedded_statement { - // $$ = new Fixed ((string) $3, $4, (Statement) $6, lexer.Location); + Block assign_block = (Block) oob_stack.Pop (); + Location l = (Location) oob_stack.Pop (); + + $$ = new Fixed ((string) $3, (ArrayList) $4, (Statement) $6, l); } ; fixed_pointer_declarators - : fixed_pointer_declarator + : fixed_pointer_declarator { + ArrayList declarators = new ArrayList (); + declarators.Add ($1); + $$ = declarators; + } | fixed_pointer_declarators COMMA fixed_pointer_declarator + { + ArrayList declarators = (ArrayList) $1; + declarators.Add ($3); + $$ = declarators; + } ; fixed_pointer_declarator - : IDENTIFIER EQUALS fixed_pointer_initializer - ; - -fixed_pointer_initializer - : BITWISE_AND variable_reference - | expression + : IDENTIFIER EQUALS expression + { + $$ = new Pair ($1, $3); + } ; lock_statement @@ -3336,8 +3383,9 @@ using_statement ArrayList var_declarators = (ArrayList) de.Value; foreach (VariableDeclaration decl in var_declarators){ - if (!current_block.AddVariable (type, decl.identifier, current_local_parameters, - decl.Location)){ + if (current_block.AddVariable ( + type, decl.identifier, + current_local_parameters, decl.Location) == null){ Report.Error (128, decl.Location, "A local variable `" + decl.identifier + "' is already" + "defined in this scope"); @@ -3611,7 +3659,7 @@ Block declare_local_variables (string type, ArrayList variable_declarators, Loca foreach (VariableDeclaration decl in variable_declarators){ - if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, decl.Location)) { + if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, decl.Location) != null) { if (decl.expression_or_array_initializer != null){ if (inits == null) inits = new ArrayList (); diff --git a/mcs/mcs/statement.cs b/mcs/mcs/statement.cs index 7b727617ddc..f1f29dc2544 100755 --- a/mcs/mcs/statement.cs +++ b/mcs/mcs/statement.cs @@ -783,31 +783,31 @@ namespace Mono.CSharp { return null; } - public bool AddVariable (string type, string name, Parameters pars, Location l) + public VariableInfo AddVariable (string type, string name, Parameters pars, Location l) { if (variables == null) variables = new Hashtable (); if (GetVariableType (name) != null) - return false; + return null; if (pars != null) { int idx = 0; Parameter p = pars.GetParameterByName (name, out idx); if (p != null) - return false; + return null; } VariableInfo vi = new VariableInfo (type, l); variables.Add (name, vi); - return true; + return vi; } public bool AddConstant (string type, string name, Expression value, Parameters pars, Location l) { - if (!AddVariable (type, name, pars, l)) + if (AddVariable (type, name, pars, l) == null) return false; if (constants == null) @@ -1702,6 +1702,44 @@ namespace Mono.CSharp { } } + // + // Fixed statement + // + public class Fixed : Statement { + string type; + ArrayList declarators; + Statement statement; + Location loc; + + public Fixed (string type, ArrayList decls, Statement stmt, Location l) + { + this.type = type; + declarators = decls; + statement = stmt; + loc = l; + } + + public override bool Emit (EmitContext ec) + { + Type t; + + t = RootContext.LookupType (ec.TypeContainer, type, false, loc); + if (t == null) + return false; + + foreach (Pair p in declarators){ + VariableInfo vi = (VariableInfo) p.First; + Expression e = (Expression) p.Second; + + e = e.Resolve (ec); + if (e == null) + continue; + } + + return false; + } + } + public class Catch { public readonly string Type; public readonly string Name; diff --git a/mcs/mcs/support.cs b/mcs/mcs/support.cs index 3cd6cf4df7d..89bfc9018e4 100755 --- a/mcs/mcs/support.cs +++ b/mcs/mcs/support.cs @@ -222,9 +222,14 @@ namespace Mono.CSharp { public object Second; public Pair (object f, object s) - { - First = f; - Second = s; - } + { + First = f; + Second = s; + } + + public void SetFirst (object n) + { + First = n; + } } } -- cgit v1.2.3