<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=iso-8859-1">
<META content="MSHTML 6.00.2800.1476" name=GENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY>
<DIV><FONT face=Arial size=2><STRONG>Problem:</STRONG></FONT></DIV>
<DIV><FONT face=Arial size=2>Various legal constructs in extended classes fail
to compile, particularly references to base class members and methods.
References to global variables in constructor code also fails.</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>See the test file given below.</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2><STRONG>Fix:</STRONG></FONT></DIV>
<DIV><FONT face=Arial size=2> chuck-emit.cpp line
3303</FONT></DIV>
<DIV><FONT face=Arial size=2> delete
3303</FONT></DIV>
<DIV><FONT face=Arial size=2>
< assert( v->owner_class ==
emit->env->class_def );</FONT></DIV>
<DIV><FONT face=Arial size=2> chuck-type.cpp line
1758</FONT></DIV>
<DIV><FONT face=Arial size=2>
< if(
!env->class_def || env->class_scope > 0 )<BR>
>
if( !env->class_def)<BR></FONT></DIV>
<DIV><FONT face=Arial size=2><STRONG>Discussion:</STRONG></FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>The assert is incorrect. The reference may be to a
base-class member, (or perhaps a global variable. I'm not sure about that). It
may be better to replace the assert with something like:</FONT></DIV>
<DIV><FONT face=Arial size=2>
assert(is_parent_type(emit->env->class_def,v->owner_class) ||
is_global_type(v->owner_class) )</FONT></DIV>
<DIV><FONT face=Arial size=2>(neither function currently
avaialble).</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>The second fix is more difficult. Generally, we
want the test to fail and go to the else clause which searches class scope for
the variable if we're in a class definition. I don't understand the purpose of
the test on class_scope, which is certainly incorrect, whatever it's supposed to
do. What I do know: class_scope is zero in constructor code, and increments for
each nested scope (function, code block &c) in the code at this point. If
the intention is to prevent references to base class or global variables in
constructure code, then it would be "env->class_scope == 0" (sense inverted);
but this seems like an arbitrary restriction on a perfectly useful
functionality, and removing the test altogether doesn't seem to cause problems
in code generation.</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>References to global variables and variables in the
current scope seem to be caught before this (which, thinking about it, suggests
that global variable references will take precedence over base-class references,
which is incorrect -- possibly another bug). The main issue seems to be
base-class references. Deleting the || test seems to correct the scanning pass,
and the generated code passes the test case given below.</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>With respect to global and base-class variables
with the same name, I wrote a test for this case (see ScopeTest-11 tests below).
The test succeeds, with the above patches applied. Both type checking and code
generation seem to work. S</FONT><FONT face=Arial size=2>o I'm not going to
hunt further.</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2><STRONG><EM>Test case for the
fix:</EM></STRONG></FONT></DIV>
<DIV><FONT face=Arial size=2><STRONG><EM></EM></STRONG></FONT> </DIV>
<DIV><FONT face=Arial size=2><EM>ScopeTest.ck</EM></FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>/////////////////////////////<BR>//
ScopeTest.ck<BR>// Test Scoping of variables and virtual functions in extended
classes.<BR>//<BR>/////////////////////////////</FONT></DIV>
<DIV> </DIV><FONT face=Arial size=2>
<DIV><BR>function void Assert(int condition, string message)<BR>{<BR> if
(!condition) <BR> {<BR> <<< "Assert Failed: ", message
>>>;<BR> }</DIV>
<DIV> </DIV>
<DIV>}</DIV>
<DIV> </DIV>
<DIV>1 => int globalVariable;<BR>Assert(globalVariable == 1,"ScopeTest-1
Global Assignment");</DIV>
<DIV> </DIV>
<DIV>string globalAndBaseclassVariable;</DIV>
<DIV> </DIV>
<DIV>class Base<BR>{<BR> int globalAndBaseclassVariable;</DIV>
<DIV> </DIV>
<DIV> 2 => globalVariable;<BR> Assert(globalVariable ==
2,"ScopeTest-2 Global Assignment from constructor.");</DIV>
<DIV> </DIV>
<DIV> 3 => int v;<BR> Assert(v == 3,"ScopeTest-3 Assigment to class
variable in ctor");<BR> <BR> function int GetV() {
<BR> return v; <BR> }<BR> function int GetVVirtual() {
<BR> return v; <BR> }<BR>}</DIV>
<DIV> </DIV>
<DIV>class Super extends Base<BR>{<BR> 4 => int v2;<BR> Assert(v2
== 4,"ScopeTest-4 Assigment to class scope from extended class.");<BR> 5
=> v;<BR> Assert(v == 5, "ScopeTest-5 Assignment to variable in
superclass.");<BR> 6 => v;<BR> Assert(GetV() == 6, "ScopeTest-6
Assignment to variable in superclass.");</DIV>
<DIV> </DIV>
<DIV> 7 => globalVariable;<BR> Assert(globalVariable == 7,
"ScopeTest-7 assignement to global variable in extended class");</DIV>
<DIV> </DIV>
<DIV> function int Test() <BR> {<BR> return
GetV();<BR> }</DIV>
<DIV> </DIV>
<DIV> function int GetVVirtual() { <BR> return
v2;<BR> }<BR> function int
GetglobalAndBaseclassVariable()<BR> {<BR> return
globalAndBaseclassVariable;<BR> }<BR>}</DIV>
<DIV> </DIV>
<DIV><BR>Base b;<BR>Assert(globalVariable == 2, "ScopeTest-2.1 constructor
side-effects in global scope.");</DIV>
<DIV> </DIV>
<DIV><BR>Super s;<BR>Assert(globalVariable == 7, "ScopeTest-7.1 superclass
constructor side-effects in global scope.");</DIV>
<DIV> </DIV>
<DIV><BR>8 => b.v;<BR>Assert(b.v == b.GetV(),"ScopeTest-8 assigment to
class-scope variable.");<BR>9 => s.v;<BR>Assert(s.v == s.GetV(),"ScopeTest-9
assigment to base-class-scope variable.");<BR>10 => s.v2;<BR>Assert(s.v ==
s.GetV(),"ScopeTest-10 assigment to super-class-scope
variable.");<BR>Assert(s.v2 == 10,"ScopeTest-10.1 assigment to super-class-scope
variable.");<BR>Assert(s.v2 == s.GetVVirtual(),"ScopeTest-10.1 virtual function
resolution.");</DIV>
<DIV> </DIV>
<DIV><BR>"110" => globalAndBaseclassVariable;<BR>111 =>
s.globalAndBaseclassVariable;<BR>Assert(globalAndBaseclassVariable ==
"110","ScopeTest-11.1 aliased global and base-class
variable.");<BR>Assert(s.GetglobalAndBaseclassVariable() == 111,"ScopeTest-11.2
aliased global and base-class
variable.");<BR>Assert(s.globalAndBaseclassVariable() == 111,"ScopeTest-11.3
aliased global and base-class variable.");</DIV>
<DIV> </DIV>
<DIV></FONT> </DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV></BODY></HTML>