In a nutshell, when we understand that the expression is a function
call (this happens at '(' after an expression), stop parsing expression
and start parsing function arguments. This makes
`FunctionCallCanonicalizationPass` and the workaround for zero argument
function calls obsolete.
RecursiveASTVisitor was recursing into the subtrees of an old root if it
was changed in on_entry callback. Fix that by querying root pointer just
after on_entry callback returns. While on it, also use
`AK::TemporaryChange` instead of setting `m_current_subtree_pointer`
manually.
As it turns out, `FunctionCallCanonicalizationPass` was relying on being
able to replace tree on entry, and the bug in RecursiveASTVisitor made
the pass to not fully canonicalize nested function calls.
The changes to GenericASTPass.cpp alone are enough to fix the problem
but it is canonical (for some definition of canonicity) to only change
trees in on_leave. Therefore, the commit also switches
FunctionCallCanonicalizationPass to on_leave callback.
A test for this fix and one from the previous commit is also included.
We cannot handle them normally since we need text between parenthesis to
be a valid expression. As a workaround, we now push an artificial value
to stack to act as an argument (it'll be later removed during function
call canonicalization).
For some reason I was afraid to add trivial accessors to classes
in earlier PRs, so we now have dozens of classes with public fields. I'm
not exactly looking forward to refactoring them all at once but I'll
do so gradually.
This commit introduces NamedVariableDeclaration and
SSAVariableDeclaration and allows storing both of them in Variable node.
Also, it adds additional structures in FunctionDefinition and
BasicBlock, which will be used to store SSA form related information.
We assume that variable shadowing is impossible, so then there is no
reason to keep distinct Declaration and Assignment operators after
ReferenceResolvingPass.
It simplifies ladders of BinaryOperators nodes in the function call
arguments into nice and neat FunctionCall node. Ladders initially appear
since I do not want to complicate expression parser, so it interprets
`f(a, b, c, d)` as `f "function_call_operator" (a, (b, (c, d))))`.
This class stores a non-owning raw pointer to a member of `Node`, so
extra care is needed to ensure that referenced `Node`s will be alive
by the time `NodeSubtreePointer` is used. Since we only need to use this
class while traversing AST in `RecursiveASTVisitor`, access to class
methods can be restricted using `Badge<RecursiveASTVisitor>`.