This removes Printer's legacy behaviour of generating an ID for each
node as it gets printed. This old method meant that if new nodes were
added to or removed from a graph, every ID after the new/removed node
would change.
Now IDs are stable so it is easier to follow specific nodes through
multiple transformation passes in CodeGen.
Names which were generated on-demand are now stored in member variables,
which are set during the ctor and can be regenerated when required (by
NameGen).
We previously only marked as packed if there was no tail padding, which
was not a sufficient condition.
The new AlignmentCalcTest.PackedMembers test case is an example which
would previously not have been marked as packed.
CodeGen v1 does not record anything for pointers to incomplete types.
Not even the address, as is done for other pointers.
Introduce a new Primitive type "Incomplete". This behaves identically to
"Void", but allows us to tell whether a type was defined as void or if
it ended up like that because of incomplete DWARF information.
This extracts the compatibility logic from AddPadding, which allows for it to be
simplified and will make it easier to extend and eventually remove in the
future. No functional changes.
This lets us remove fields from types when they are no longer needed,
speeding up later passes.
A secondary benefit of pruning unused types means that we sometimes
remove types for which we can't generate correct C++ code. This can
allow us to CodeGen for complex types which reference these broken types
without actually requiring them (e.g. as template parameters).
Add a new feature flag "prune-type-graph" to control this pass. It makes
sense to prune most of the time, but for testing CodeGen functionality
on a wider range of types, it will be useful to have the option to not
prune.
In general, we can't tell which member is active in a union so it is not
safe to try and measure any of them.
Explicitly set the alignment of unions (and structs/classes) in CodeGen
if it is available, as the C++ compiler can no longer infer it from the
members.
Also reshuffle CodeGen's passes to fix an alignment bug with removed
members.
Change RemoveMembers to actually remove members instead of replacing
them with padding. AddPadding must be run afterwards to fill in the
gaps.
The underlying type of bitfield is important to the size of a struct:
struct Foo { int64_t bitfield : 1; };
struct Bar { int8_t bitfield : 1; };
sizeof(Foo) = 8;
sizeof(Bar) = 1;
Previously this code would not have removed all members which it was
supposed to.
Also remove some now-redundant code from TypeIdentifier. RemoveIgnored
will take over the responsibility of removing members from classes.
Containers store references to ContainerInfos, so the ContainerInfos
must live beyond the stack they were created on. Use static variables
for simplicity.
We can catch these exceptions and print clearer failure messages.
Before:
unknown file: Failure
C++ exception with description "Invalid type for child" thrown in the test body.
After:
../test/type_graph_utils.cpp:44: Failure
Failed
Error parsing input graph: Invalid type for child
i.e. unions with non-POD members
We can't examine untagged unions, but we should be able to support
looking inside tagged unions at some point in the future.
TypeGraphParser parses a textual type graph, as emitted by Printer.
It also doubles as a way of ensuring that Printer displays all
information about a type graph, to aid with debugging.
Convert Flattener unit tests over to this new framework as a first step.