Functions for gathering all the expressions used in lvalue positions throughout a module item.
Like the allexprs family of functions, these functions gather up "top level" expressions found throughout various module items that occur in "lvalue positions."
Roughly speaking, the lvalexprs functions try to return all expressions that are being driven by assignments or submodules. But lvalue gathering is something of a crapshoot, and you should regard these functions as a sort of best-effort, heuristic approximation of the actual expressions that are being driven. More specifically, you should never assume that the expressions returned by lvalexprs functions are in any way accurate or complete.
In some cases, the syntax of the module item makes clear which expressions
should be gathered by the corresponding
But gathering the lvalues from module instances is more involved. Here, we need to know which ports are inputs and outputs, which we do not know until the argresolve transform is run. Even then, the situation is complicated because (1) due to "backflow" it is not necessarily the case that inputs to the submodule are undriven, and (2) the submodule might not actually drive all of its outputs.
We try to take these into account as best we can. For the most accurate results you should typically only run lvalexprs after first running argresolve and the backflow detector. If we see that an output has been flagged as undriven, we will not include the connected wire as an lvalue. Similarly, if we see that an input has some backflow, it will be included.
We guarantee that every expression returned by the lvalexprs functions will satisfy vl-expr-lvaluep. In certain cases, this may require us to omit certain "bad" expressions. We print warnings to standard out when this happens, but there is no way for the caller to programmatically determine if this has happened.
BOZO proper handling for port expressions?
BOZO we don't do anything with function declarations. This seems basically reasonable; if the functions can be expanded away then we shouldn't see them, and if they aren't expanded away then we don't really want to include their "wires" since they're in a different namespace.