It's not much cleaner due to arithmetic to convert truncating division to a ceiling, but has two advantages:
1. It doesn't suffer from rounding issues with large TRAP labels. This is largely theoretical, but does let us handle `undefined` uniformly.
2. It should be much faster (using LZCNT/BSR instead of floating point arithmetic). This is probably not a performance bottleneck, so *shrug*.
The information that was contained in `schema.yml` is now in
`swift/schema.py`, which allows a more integrated IDE experience
for writing and navigating it.
Another minor change is that `schema.Class` now has a `str` `group`
field instead of a `pathlib.Path` `dir` one.
Now `TypeRepr` is a final class in the AST, which is more or less just
a type with a location in code.
As the frontend does not provide a direct way to get a type from a
type representation, this information must be provided when fetching
the label of a type repr.
This meant:
* removing the type repr field from `EnumIsCaseExpr`: this is a virtual
AST node introduced in place of some kinds of `IsEpxr`. The type
repr is still available from the `ConditionalCheckedCastExpr` wrapped
by this virtual node, and we will rebuild the original `IsExpr` with
the IPA layer.
* some logic to get the type of keypath roots has been added to
`KeyPathExpr`. This was done to keep the `TypeRepr` to `Type` relation
total in the DB, but goes against the design of a dumb extractor. The
logic could be moved to QL in the future
* in the control flow library, `TypeRepr` children are now ignored. As
far as I can tell, there is no runtime evaluation going on in
`TypeRepr`s, so it does not make much sense to have control flow
through them.
Visitor code has been split between header and sources to speed up
incremental build. Moreover the code was reorganized using a new `infra`
bazel package (and `visitors` got promoted to a bazel package as well).
This adds:
* a base `README.md` file to `codegen`
* module docstrings for the modules in `generators`
* help strings on all command line flags
Moreover some unneeded command line flags (`--namespace`,
`--include-dir` and `--trap-affix`) have been dropped.
Python code was simplified, and now a `--generate` option can be used
to drive what can be generated.
The extractor pack creation now will use an internally generated
dbscheme. This should be the same as the checked in one, but doing so
allows `bazel run create-extractor-pack` and `bazel run codegen` to be
run independently from one another, while previously the former had to
follow the latter in case of a schema change. This is the change that
triggered the above simplification, as in order for the two dbscheme
files to be identical, the first `// generated` line had to state the
same generator script.
This is solving a papercut, where the C++ build was relying on the
local dbscheme file to be up-to-date, even if all the information for
building is actually in `schema.yml`. This made a pure C++ development
cycle with changes to `schema.yml` clumsy, as it required a further
dbscheme generation step.
Now for C++ the dbscheme is generated internally in the build files, and
thus a change in `schema.yml` is reflected immediately in the C++ build.
A `swift/codegen` step for checked in generated code (including the
dbscheme) is still required, but a developer can do it just before
running QL tests or committing, instead of during each C++
recompilation.
Some directory reorganization was also carried out, moving specific
generator modules to a new `generators` python package, and only leaving
the two drivers at the top level.
This checks in the trapgen script generating trap entries in C++.
The codegen suite has been slightly reorganized, moving the templates
directory up one level and chopping everything into smaller bazel
packages. Running tests is now done via
```
bazel run //swift/codegen/test
```
With respect to the PoC, the nested `codeql::trap` namespace has been
dropped in favour of a `Trap` prefix (or suffix in case of entries)
within the `codeql` namespace. Also, generated C++ code is not checked
in in git any more, and generated during build. Finally, labels get
printed in hex in the trap file.
`TrapLabel` is for the moment only default-constructible, so only one
single label is possible. `TrapArena`, that is responsible for creating
disjoint labels will come in a later commit.