The goto for the default expression is the source of the mis-counted label
users: the label was being counted by the goto, but the goto was never
being inserted into the code (only v6 progs or "difficult" types insert the
goto).
Such nodes are unreachable code (ie, dead blocks), but the dead block
removal code failed to remove them (current known cause: miscounted label
userrs). As such blocks cause problems for data flow analysis, ignoring
them is not a good idea. Thus make them an internal error.
vectors, quaternions and structs are a little tricky. I need to think about
how to get them working, but I also want qfcc to get through as much code
as possible.
While accessing short foo[2][4]; as foo[0][0..7] should work in theory, who
knows what gcc does with it when optimizing. I don't know if this will fix
johnnyonflame's bsp loading problem, but no point in having rhinodemonic
code hanging around.
The evil comment is not just "pragmas are bad, ok?", but switching between
advanced, extended and tradtitional modes when compiling truly is evil and
not guaranteed to work. However, I needed it to make building test cases
easier (it's mostly ok to go from advanced to extended or tradtional, but
going the other way will probably cause all sorts of fun).
In the process, opcode_init now copies the opcode table data rather than
modifying it.
After running across a question about lists of animation frames and states,
I decided giving qfcc the ability to generate such lists might be a nice
distraction from the optimizer :) Works for both progs.src and separate
compilation. No frame file is generated if no macros have been created.
It really should be impossible, but I'm not sure where the bug is yet
(though there are uninitialized variables that are false positives that
most definitely are initialized, might be related)
Pointing to aliases of the var causes all sorts of problems, but this time
it was causing the uninitialized variable detector to miss certain
parameters.
It is necessary to know if a def is a function parameter so it can be
treated as initialized by the flow analyzer. The support for the flag in
object files is, at this stage, purely for debugging purposes.
The structvar2 = structvar1 is implemented as a move expresion, which
address_expr didn't like. Return the address of the source. For indirect
move expressions, this is just the source expression itself.
Constant/label nodes should never be killed because they can (in theory)
never change. While constants /can/ change in the Quake VM, it's not worth
worrying about as there would be much more important things to worry about
(like 2+2 not giving 4).
Due to the hoops one would have to jump through, it is assumed that a
pointer or an offset from that pointer will never overwrite the pointer.