A4GL_MARK_SCOPE (and MARK_SCOPE_MODULE) prefixes variables with their scope -
G_ for globals, M_ or M_<module>_ for module variables, L_ for locals - so a
4GL name cannot collide with a C one. For the C back end it only ever renamed
the DECLARATION: every use still emitted the bare name, so a module with a
variable in it produced
static long M_dup ;
...
dup=0;
and did not compile. Only the C# back end, which applies the prefix wherever a
name is written, actually worked. So the one setting meant for this problem
could not be used for it.
The declaration and every use now take the name from one function,
scoped_variable_name(), so the two cannot drift apart again - expressions,
assignments, function and report parameter binding, nullify, dynamic arrays,
the object list and COPYBACK all go through it.
- system variables (status, sqlca, int_flag...) live in the library and keep
their names; a use is looked up to recognise them, as only the definition
records that
- class members and associative arrays keep the plain name: they are declared
through their own paths (objData->..., the ASSOCIATE_ macros)
- simple and object function parameters had no scope recorded at all, so they
were never prefixed; they are now marked local, as record and reference
parameters already were
- a CODE block is hand written C that names variables as the 4GL wrote them,
so each variable a block mentions is #defined to its scoped name for the
length of the block and #undef'd after. Only the block sees the aliases, so
generated code keeps the protection. Without this every tool with embedded
C - 4glpc, asql, adbschema, a4gl - failed to compile under the flag.
Checked on 142 modules from tools/ and the test suite compiled three ways - no
flag, MARK_SCOPE, MARK_SCOPE_MODULE: the same 108 compile in all three, and the
34 that fail fail identically, all for reasons that predate this. With no flag
set the generated C is byte for byte what it was, bar the cursor and prepare
identifiers that differ on every compile. Runtime output is identical in all
three modes for a program exercising globals, module variables, locals,
records, arrays, dynamic arrays, a report and variables called dup, read, write
and close; for both OO test programs; and for a 4glpc built with the flag and
then used to compile and run a program. ESQL/C output compiles through Informix
esql with either flag. A clean export of r13115 with this change builds with 0
errors and the same 361 warnings as without it.
Two things the flag cannot do: C outside the module must use the prefixed name
of a GLOBALS variable, and if a name is both a 4GL variable and a struct member
used across CODE blocks the aliasing renames the member too - a compile error,
not a silent change of meaning.
The description of A4GL_MARK_SCOPE said it adds the module name, which is what
MARK_SCOPE_MODULE does; corrected, and MARK_SCOPE_MODULE is now described too.