Emit forward declarations and definitions of the opaque-array
artificial structs from the C model header (and from the helpers
header). Definitions are gated on a new DefineOpaqueTypes flag
threaded through PTMLHeaderBuilder::printModelHeader so that the
helpers header keeps emitting only the declarations.
This allows the existing annotation registry to be reused in a more
convenient nature. Before now, it was only used for *parsing* or,
rather, *verifying* annotations. Now that we can take advantage of
it for emission as well, there's more control it needs to provide
in particular as far as annotation arguments are concerned.
* Make the following private headers public:
* Lift/CPUStateAccessAnalysisPass.h
* Lift/CSVOffsets.h
* Lift/PTCDump.h
* Lift/VariableManager.h
* Move from revngSupport to revngLift:
* IRAnnotators.{h,cpp}
* SelfReferencingDbgAnnotationWriter.{h,cpp}
* Move from revngSupport to revngModel:
* FunctionTags.{h,cpp}
* ProgramCounterHandler.{h,cpp}
* Move from revngSupport to revngRecompile:
* OriginalAssemblyAnnotationWriter.{h,cpp}
Type inlining was a feature that allowed type definitions of
structs/unions/enums to be printed in C directly inside the definition
of another parent struct/union, if the inner type was only used once in
the parent type.
This kind of reasoning is inherently global: a type definition of the
subtype can be inlined in the parent type one only if *globally* the
subtype it isn't referred anywhere else.
This caused issues with type inlining inside definitions of stack types
in the body of functions. Indeed, for a given function, due to type
inlining, it was necessary to do global reasoning about what other types
could be inlined in the definition of the function's stack frame type.
This, in turn, had heavy consequences on invalidation, because any
change to any type (even if it wasn't referred in a given function's
body) was causing invalidation of all functions' bodies.
For this reason it was decided to drop the type inlining feature.
Now addNodes also adds an implicit dependency from the declaration node
to the definition node, and returns a data structure representing the
two nodes: declaration and definition.
This commits wraps all the machinery that can mutate a DependencyGraph
inside the interval factory class DependencyGraph::Builder.
In this way, once a DependencyGraph is created, it cannot be mutated by
accident from outside.
This is important because mutating it from outside makes it easy to
break the consistency of internal maps.
This risk will only increase when supporting artificial struct wrapper
types, so we encapsulate this now to prevent issues in the future.
This data structure is used to bind together a pair of pointers to
TypeDependencyNode, one referring to a declaration of a type and the
other referring to a definition of the same type.
The definition can be null if the type referred to is a type without an
explicit definition (e.g. typedefs), while it's never null for types
for which have forward declaration that is separate from the definition
(e.g. structs and unions).
This commit adds two enum entries to TypeNode::Kind to represent forward
declarations and definitions of artificial struct wrappers, that are not
present in the model but that we're forced to print in C to overcome
its limitations in representing types.
At the moment, this is only going to be used for representing return
types of RawFunctionDefinitions whose Layout returns RegisterSet, which
can't be represented in C without a wrapper.
This commit bans from the model array types in as argument or return
types in CABIFunctionDefinition.
CABIFunctionDefinition implies we're decompiling towards C, and C does
not support array arguments (passed by copy) nor array return types.
Banning these from the model reduces the number of situations where we
have to emit artificial array wrappers (not present in the model) around
types when printing C code, simplifying the handling of such situations
when translating to clift and in general in the decompilation pipeline.
Before this, commenting is only possible on specific names, with this
the entire supported line is active (unless there are more grannular
comment contexts, for example, in the function prototype).
For example (commentable parts are marked with `^`):
```
// struct whatever {
// ...
// before this
const my_type_name *my_field_name[10];
// ^^^^^^^^^^^^^
// after this
const my_type_name *my_field_name[10];
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// ...
// };
```
It's the same for all the others, like segments, arguments, and so on.