* class.cs: Only report 108 if there is no `new' modifier.
* cs-parser.jay: rework foreach statement to work with the new
changes to the policy on SimpleNames.
* report.cs: support Stacktrace on warnings as well.
* makefile: drop --unsafe and /unsafe from the compile.
2002-03-11 Miguel de Icaza <miguel@ximian.com>
* ecore.cs (SimpleName.SimpleNameResolve): Perform local variable
lookups here, instead of doing that at parse time. This means
that our grammar will not introduce `LocalVariableReferences' as
expressions at this point. That solves the problem of code like
this:
class X {
static void Main ()
{ int X = 1;
{ X x = null }}}
This is only half the fix. The full fix requires parameters to
also be handled in this way.
Added test for the above new scenario, updated our foreach tests to try
the new changes.
svn path=/trunk/mcs/; revision=3059
+2002-03-12 Miguel de Icaza <miguel@ximian.com>
+
+ * class.cs: Only report 108 if there is no `new' modifier.
+
+ * cs-parser.jay: rework foreach statement to work with the new
+ changes to the policy on SimpleNames.
+
+ * report.cs: support Stacktrace on warnings as well.
+
+ * makefile: drop --unsafe and /unsafe from the compile.
+
2002-03-11 Miguel de Icaza <miguel@ximian.com>
+ * ecore.cs (SimpleName.SimpleNameResolve): Perform local variable
+ lookups here, instead of doing that at parse time. This means
+ that our grammar will not introduce `LocalVariableReferences' as
+ expressions at this point. That solves the problem of code like
+ this:
+
+ class X {
+ static void Main ()
+ { int X = 1;
+ { X x = null }}}
+
+ This is only half the fix. The full fix requires parameters to
+ also be handled in this way.
+
* class.cs (Property.DefineMethod): When implementing an interface
method, set newslot, when implementing an abstract method, do not
set the flag (before we tried never setting it, or always setting
+NOTES:
+ I am trying to remove the LocalVariableReference from the code
+ but the compiler does not pass its own self-compilation.
+
+ The problem is that constructs with embedded_statements like:
+
+ foreach (int b in X)
+ if (b ...)
+
+ The ec.CurrentBlock is not updated with the fact that `b' lives
+ in an implicit internal block, and the lookup is attempted on the
+ parent's block, hence rendering the lookup invalid.
+
Major tasks:
------------
* Emit warning on hiding members without NEW not only in members.
* Implement visibility.
-
+
+* Casts need to trigger a name resolution against types only.
+
* Adding variables.
We do add variables in a number of places, and this is erroneous:
// then: `continue;'
}
#endif
- Report108 (mc.Location, defined_names [idx]);
+ if ((mc.ModFlags & Modifiers.NEW) == 0)
+ Report108 (mc.Location, defined_names [idx]);
}
foreach (object o in remove_list)
%{
//
+// OPTIMIZATION:
+// This loop is pointless:
+// while (current_block != prev_block)
+// current_block = current_block.Parent;
+//
// cs-parser.jay: The Parser for the C# compiler
//
// Author: Miguel de Icaza (miguel@gnu.org)
statement_expression_list
: statement_expression
{
- Block b = new Block (null, true);
+ // CHANGE: was `null'
+ Block b = new Block (current_block, true);
b.AddStatement ((Statement) $1);
$$ = b;
}
v = new LocalVariableReference (foreach_block, (string) $4, l);
-
- current_block.AddStatement (foreach_block);
current_block = foreach_block;
oob_stack.Push (v);
+ oob_stack.Push (current_block);
}
embedded_statement
{
+ Block foreach_block = (Block) oob_stack.Pop ();
LocalVariableReference v = (LocalVariableReference) 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;
+ current_block = prev_block;
- $$ = new Foreach ((string) $3, v, (Expression) $7, (Statement) $10, l);
+ Foreach f = new Foreach ((string) $3, v, (Expression) $7, (Statement) $10, l);
+ foreach_block.AddStatement (f);
+
+ $$ = foreach_block;
}
;
CheckDef (AdditionResult.NameExists, name);
}
+//
+// This routine should be removed soon. I am in the process of making
+// changes to never keep anything but SimpleNames during parsing, as
+// that breaks some kinds of code (documented in the ChangeLog).
+//
Expression
SimpleLookup (string name, Location loc)
{
// as `expression' is allowed in argument_lists, which
// do not exist inside a block.
//
+#if BLAH
if (current_block != null){
- if (current_block.IsVariableDefined (name))
+ if (current_block.IsVariableDefined (name)){
return new LocalVariableReference (current_block, name, loc);
+ }
}
+#endif
if (current_local_parameters != null){
int idx;
if (e != null){
if (e is SimpleName){
SimpleName s = (SimpleName) e;
-
+
Report.Error (
103, s.Location,
"The name `" + s.Name + "' could not be found in `" +
//
// Stage 1: Performed by the parser (binding to locals or parameters).
//
+ Block current_block = ec.CurrentBlock;
+ if (current_block != null && current_block.IsVariableDefined (Name)){
+ LocalVariableReference var;
+
+ var = new LocalVariableReference (ec.CurrentBlock, Name, Location);
+ return var.Resolve (ec);
+ }
+
//
// Stage 2: Lookup members
//
CSC=csc.exe
-CSCFLAGS=/nologo /debug+ /debug:full /optimize /unsafe
+CSCFLAGS=/nologo /debug+ /debug:full /optimize
VERSION=0.13
./mcs --fatal --target exe -o mcs2.exe $(COMPILER_SOURCES)
mcs2.exe: mcs.exe
- ./mcs $(XFLAGS) --target exe --unsafe -o mcs2.exe $(COMPILER_SOURCES)
+ ./mcs $(XFLAGS) --target exe -o mcs2.exe $(COMPILER_SOURCES)
mcs3.exe: mcs2.exe
- ./mcs2 --target exe --unsafe -o mcs3.exe $(COMPILER_SOURCES)
+ ./mcs2 --target exe -o mcs3.exe $(COMPILER_SOURCES)
mm:
mint ./mcs.exe --target exe -o mcs4.exe $(COMPILER_SOURCES)
l.Name, row, code, text));
Warnings++;
Check (code);
+
+ if (Stacktrace)
+ Console.WriteLine (new StackTrace ().ToString ());
}
}
variables.Add (name, vi);
+ // Console.WriteLine ("Adding {0} to {1}", name, ID);
return vi;
}
/// </summary>
public bool IsVariableDefined (string name)
{
+ // Console.WriteLine ("Looking up {0} in {1}", name, ID);
if (variables != null) {
if (variables.Contains (name))
return true;
test-51 test-52 test-53 test-54 test-55 test-56 test-57 test-59 \
test-61 test-62 test-63 test-64 test-65 test-66 test-67 test-68 test-69 test-70 \
test-71 test-72 test-73 test-74 test-75 test-77 test-78 test-79 test-80 \
- test-81 test-82 test-83
+ test-81 test-82 test-83 test-84
UNSAFE_SOURCES = \
unsafe-1 unsafe-2
if (total != 6)
return 1;
+
+ total = 0;
+
+ //
+ // implicit block
+ //
+ foreach (object a in x)
+ total += (int) a;
+ if (total != 6)
+ return 2;
+
return 0;
}
}
--- /dev/null
+//
+// This test shows how a variable can be created with the
+// same name as the class, and then the class referenced again
+//
+// This was a bug exposed by Digger, as we incorrectly tried to
+// do some work ahead of time during the resolution process
+// (ie, we created LocalVariableReferences for the int variable `Ghost',
+// which stopped `Ghost' from being useful as a type afterwards
+//
+
+class Ghost {
+
+ static int Main ()
+ {
+ int Ghost = 0;
+
+ if (true){
+ Ghost g = null;
+ }
+ return 0;
+ }
+}