Before this commit, char literals were always printed with html
escaping, even if the associated PTML builder was set to Tagless.
This commit fixes the problem.
This is due to the fact that type inlining currently is broken in some
corner cases involving recursive types.
The bugs are caused by the fact that TypeInlineHelper uses its own
custom graph instead of using the DependencyGraph used by ModelToHeader,
causing different decisions about the order of emission of types.
As a result, the generated C types are not valid C, and they fail to
compile because a field of a struct has a type that is defined later
than its use.
After refactoring TypeInlineHelper to use DependencyGraph like
ModelToHeader, this can be reverted.
At the moment in C we can't emit variable declarations with inline
initialization. Not for some substantial problem, but we haven't
implemented it yet. As a result if TypeMap.at(VarDeclCall) returns a
const-qualified type we will end up generating C code that doesn't
compile, when it tries to assign a value to the variable for
initializing it separately from the declaration.
To work around this, until we don't support emission of variable
declarations with inline initialization, we have to strip away
constness.
We introduce a new LLVM Pass that should detect implicit
casts, by marking the 3rd argument of ModelCast as `true`.
The backend will omit printing a cast expression if the
ModelCast is implicit one.
Various improvements to the debug graphs for `restructure-cfg` and
`beautify`:
- Normalize casing and syntax of debug graphs.
- Improve the graph folders name and layout.
- Implement `CFGDumper` and `ASTDumper` for when we need a serialization
with incremental indexes.
- Remove old and stale graph serializations.
Perform the ALAP Variable Declaration process.
The process is structured in the following stages:
- We start by collecting all the `Variable`s that need to be assigned in
a `ASTNode`.
- We build a `GenericGraph` where each `ASTNode` is connected with its
child nodes, and also its immediate successor.
- We perform a walk in post order over this graph, and for each
`ASTNode` we decide if the current node could be the ALAP location
where we can declare the `Variable`, i.e., where we dominate all its
uses.
Explicitly casting to uint8_t has the semantics of truncating, in case
the value being casted is larger than 8 bits.
Avoiding the cast default to regular C behavior, where every non-zero
integer is considered true.
Fix the needed attributes to allow navigation from the use of an
artificial return struct for raw functions to their definition in
`types-and-globals.h`.
We introduce the `InlineDispatcherSwitch` beautify pass. Its goal is to
try and inline the body of some of the `case`s of a exit dispatcher, in
place of the `SetNode` corresponding to that `case`, if this doesn't
introduce duplication in the code (i.e., a single `SetNode` for that
specific case value is present).
Additionally, if the inlining procedure is able to completely remove the
necessity of an exit dispatcher altogether, the pass removes it.
The pass is able to handle chains of weaved dispatcher `switch`es
referring to the same original dispatcher `switch`, by handling the
inline operation and the possible simplification level-wise.
The inlining procedure, cannot take place if a `SetNode` is contained in
the body of the case we are trying to inline, since this can possibly
break the semantics of the state variable of a loop, by placing a
`SetNode` in a more internal loop.
This commit drops `needsTopScopeDeclaration`.
Now all the LocalVariables are declared at the top of the function.
In DecompileFunction.cpp, the emission of LocalVariables if handled at
the scope of GHAST `ASTNode`s instead of being LLVM BasicBlock-based.
This enables in the future to design and implement an analysis that for
each LocalVariable decides the C scope (represented by an `ASTNode`)
where it's declaration should be emitted to always be visible in all its
uses.