When DLA is activated, a larger variety of combinations between integers
and pointers operands need to be handled when emitting C code from LLVM
Instructions.
This commit removes some assertions that do not hold anymore about some
operands not being pointers, handles a set of new cases with strange
mixtures of pointer and integer operands, and introduces a fail path for
cases that are not handled when emitting code based on DLA results.
This commit is just a skeleton. In order to actually build those member
accesses, we still need to compute the proper nested dla::Layouts for
which we want to emit those member accesses.
This commit fixes a bug due to interacting behaviors between
MarkForSerialization, AddSCEVBarrierPass, and the emission in C of calls
to revng_init_local_sp.
These interacting behaviors caused the following quirks:
- At the beginning of Functions that contained a call to
`revng_init_local_sp()`, that call was actually emitted twice.
The first time was due to the actual call to `revng_init_local_sp()`,
while the second was due to the first call being wrapped from a call
to `revng_scev_barrier_*`.
Now we properly emit only one call.
- The original call to `revng_init_local_sp()` was supposed to generate
a local variable, to be used in various places across the function.
However, due to the fact that the call was not properly labeled by
MarkForSerialization, there was no local variable, causing calls to
`revng_init_local_sp()` to be scattered around the body of the
functions, follwed by various arithmetic operations.
This behavior has been fixed as well, and we now emit the local
variable correctly.
This commits enable the emission of rich types associated with function
signatures. This types are forward-declared in the decompiled C code
before the definition of each decompiled function that uses them.
The types we emit for now are the types that the DLA is able to compute
(if any) for the return values and the arguments of the function.
Such types are not yet used in the body of the function, nor in the
function declaration. These are the next steps to come.
Before this commit, logical operators (&&, ||, !) were never emitted in
C. Bitwise operators were used instead (&, |, ~), relying on the
implicit equivalence of meaning.
This commit enables the emission of logical operators when the operands
are boolean types, making the emitted C more readable.
Before this commit, the logic to generate all the emitted C forward
declarations (types, global variables, and functions) that has to be
printed before each decompiled function was scattered across three
classes: FuncDeclCreationAction, TypeDeclCreationAction, and
GlobalDeclCreationAction.
These are all gone now, because the scattered logic was very confusing
to follow. Now we only have a single class that takes care of
declarations with global scope: DeclCreator.
Thanks to this, I was able to drop a bunch of useless layers of software
engineering used to shape the creation of the declaration as if it was
some kind of clang ASTConsumer, which is pointless.
This class handles the creation of type declarations in clang's AST, and
holds the relationships between llvm Types and Values with those clang's
type declarations.
Before this commit, we assigned names to struct types without looking at
the function names of which they were return types.
Now we do, so that the name of the generated type for the function `f`
is `f_ret_type`.
This also fixes errors when reparsing the generated C code, where the
names of the struct types did not match.
With this commit `ExtractValueInst`s are handled so that they don't have
side effects.
This significantly improves the quality of the decompiled output,
preventing the forced serialization of all the extraction of struct
fields after calls to function that return structs, except for when it's
really needed.
With this commit, the declarations of local variables and function
parameters now use the name of the associated `llvm::Value` if present,
instead of always using the prefix "param_" or "var_".
Before this commit, when GlobalDeclCreationAction needed to emit
literals for initialization of global variables, it did it using
custom code.
This was not working properly, an in some cases it emitted short
literals which are not allowed in C.
Hence the generated C code that was impossible to recompile without
syntax errors.
This commit fixes this problem, using the getLiteralFromConstant method
of StmtBuilder.
In order to do this, we need to make the StmtBuilder available inside
the GlobalDeclCreationAction, which is not a very clean design.
However, we are already planning to merge the GlobalDeclCreationAction
and the StmtBuilder class, so this issue will be taken care of in the
future.
Replicate the changes made by this commit
f2a0df309f78e1b5d7c5f81ada5110523644559e perfomed by Pietro on the
branch containing the development fixes for `revng-c`.
Handle `InsertValue` instructions which provide a `ConstantStruct` as
initialization.
A new value declaration at the top of the function is emitted and later
used as initilization for the struct which is being populated.
Handle the emission of variadic functions (such as the
`indirect_handler` helper function) both in regards if declaration and
definition.
Handle also `undef` values in calls to the `indirect_handler` function.