Change the AST debug printing from a recursive descent on the AST nodes
in the graph, to an iterative printing of respectively nodes and their
outgoing edges.
Also, we now print the edge going to the `Successor` field, if present.
Reorganize the AST dot printing in order to use LLVM facilities for
files handling. In addition, clean up the code, and add a function
(useful in debug) in order to dump the dot of and AST from GDB (accepts
a `char *` instead of a `std::string`.
Now, when the `debug-log=restructure` flag is active, debug graphs are
organized in a more rational way.
First of all, all the graphs are now put in a single directory, and are
divided first by function name and then by type.
Also, as in the case of the tiling debug graphs, their name is more
consistent with the rest of the codebase.
The simplifyLastContinue beautifier was too ambitious and there were
many corner cases that it handled in the wrong way, leaving the AST in a
shape that could not be emitted, or breaking the semantics.
This commit severely weakens the simplifyLastContinue, so that it does
not break things anymore.
It is now able to match only continue statements that are in the last
position of a sequence node which is the body of a ScsNode.
This obviously is not enough but allows revng-c to pass all the
decompilation tests.
In the future we will need to extend simplifyLastContinue to match more
cases in a sane way.
Count the number of duplication (needed later in the `Mark` pass) right
before the AST generation phase, where the `RegionCFG` will be destroyed
by the tiling matching.
Change the interface of the `findReachableNodes` helper function, so
that now accepts arguments passed by pointer instead of by reference.
Also, the helper function now does not accept a `nullptr` `Source`
parameter.
The `Successors` and `Predecessors` field on the `BasicBlockNode` are
now promoted from being a `std::pair` composed by the pointer to the
successor and the set representing the cases, to a pair between the
pointer to the successor and a new struct called `EdgeInfo`.
This struct is used to contain both the information about the cases, the
information representing whether and edge is inlined or not, and
possibly more information in the future.
Before this commit, the original llvm BasicBlock was not embedded
properly in the GHAST SwitchNodes. This caused problems and crashes in
decompilation.
This commit SwitchNode constructors so the that the BasicBlock properly
reaches the GHAST and it is printed correctly by the decompiler.
Before this commit, the C statements before an IfNode or a SwitchNode
were not guaranteed to be emitted if they were not involved in the
computation of the branch condition.
This commit fixes this problem.
This was broken after the introduction of `SwitchDispatcherNode`,
because
both `SwitchDispatcherNode` and `RegularSwitchNode` used the `isEqual`
method from `SwitchNode`.
Now the `isEqual` method is implemented only for the `ASTNode` base
class, and each leaf of the llvm-RTTI hierarchy of `ASTNode` properly
implements the comparison.
In presence of a switch node, which contains a case made up of
entirely a sequence of empty nodes (simplified by the
`simplifyAtomicSequence` recursive function), enable the removal of the
aforementioned case from the switch node.
This commit removes a call to untangle() that was performed before the
whole combing algorithm on the root RegionCFG.
The call was redundant before introducing the weaving, and became
plainly wrong after adding the weaving, because it ended up trying to
untangle the root RegionCFG before weaving (which is supposed to run
first).
Removing the dedicated call fixes the bug, because weaving is performed
first as part of the call to generateAst().
We now emit `RegularSwitch` node type creating the vector containing the
case values by inspecting the actual values of the `ConstantInt` in the
IR.
Due to the introduction of weaving, we can have a cascade of switches,
and in this case the top switch should bring to a certain weaving switch
for multiple values of the case label.
For this reason, switch case are now represented by sets, which are
usually populated by a single value, but in presence of a weaving
switches they can represent the fact that for each value contained in
the set we must take a certain case label.
The backend of the decompiler has been updated to reflect this change,
in order to emit all the values for a certain `CaseSet` in `or` if the
size of the seat is greater than 1.
Reorganize attribute `Kind` incorporating it into the `Type` attribute,
by lowering its memory footprint.
Modified the constructors, some accessors and helpers accordingly.