Introduce implicit statements simplification phase, specifically:
- A implicit `return` simplification: `return` statements in `void`
type functions, which are not followed by any other scope, can be
omitted.
- A implicit `continue` simplification: `continue` statements whose
fallthrough leads directly to the end of the cycle scope (i.e., to
execute another iteration of the enclosing loop), can be omitted.
In order to avoid the printing of the implicit `return`, we need an
additional `emitReturn` parameter in the `emitBasicBlock` method of the
`CCodeGenerator` class.
This commit reorders the argument passed to various `printDeclaration`
and `printDefinition` helper functions, to make them more uniform across
each other, and to accept the same arguments in the same order.
This commit:
* Introduces `_` as a prefix for all non-user entities we emit in
decompiled code.
Also, some names have been changed to be more concise.
Specifically, the following entities have changed:
`_ENUM_UNDERLYING`, `_ABI`, `_REG`, `_padding_at_`,
`_artificial_struct_`, `_artificial_wrapper_`, `_stack`,
`_break_from_loop_`, `_var_`, `_stack_arguments`,
`_artificial_struct_returned_`, `_enum_max_value_`.
* Introduce _PACKED for `__attribute__((packed))`.
* `EnumEntry` name: drop the `EnumType` name prefix.
Before this commit, we used to decomple UndefValue to the literal 0.
This was causing problems in some cases, such as switch(0 /*undef*/)
where clang was issuing a warning that was impossible do disable without
turning off -Wall alltogether, which is undesirable.
This commit introduces a set of helper functions in
revng-primitive-types.h, that are now used to avoid emitting undef as
constant.
This is more semantically meaningful when looking at the decompiled
code, and it has the nice side effect that it silences the clang
warnings mentioned above.
Now extractvalue instruction are replaced by dedicated
OpaqueExtractValue custom opcode, that prevents LLVM from doing strange
things with extractvalues during optimizations (such as e.g. sinking).
This is important since extractvalue instructions and struct-typed
values in general in our LLVM IR are not real first-class citizens, but
only a byproduct of the binary lifting process, and they actually
represent bundles of registers that are returned from isolated
functions.
This commit enables to emit accesses with the square bracket array
access operator on pointers.
This is accomplished by adding an additional mandatory argument to
ModelGEP (AND NOT to ModelGEPRef) to represent this case.
MakeModelGEPPass is updated to take this into account, together with all
the other passes that handle ModelGEPs.
Not equal is handled separatedly during the decompilation process in
order to add the appropriate cast.
Currently, the code only triggers when the not equal is the outermost
operation in the expression - case for which there are no tests in the
test suite.
In ModelToHeader generate Inline Types in PTML by handling
Structs, Unions and Enums.
In addition, during the ModelToHeader we avoid producing
Structs that describe stacks, and in the DecompileFunction we
produce the definition of it inline if it is safe (referenced
only once).