codeql
codeql copied to clipboard
Swift: first prototype of a generated IPA layer
This introduces a first version of a generated IPA layer.
Schema
In schema.yml, types can be marked with either
MyType:
_ipa:
from: OtherType
or
MyType:
_ipa:
on:
arg1: OtherType
arg2: int
The former are "derived" IPA types, built on top of DB entities, the latter are "fresh" ones, built from scratch.
New generated files
Db.qll defines a thin non customizable QL class layer over DB types, inside a Db module. So for example Db::Expr is a simple wrapper of @expr.
Ipa.qll defines the base algebraic type Ipa::TElement with all pure DB types and IPA types as defined in schema.yml. IPA types get characteristic predicates (except for parameterless derived IPA types) to be customized in stubs (MyTypeConstructor.qll) alongside the other stubs already created. DB types that have one or more derived IPA types built on top of them also have a characteristic predicate subtracting those derived types from their instances. The rest of the type hierarchy is recreated via class = ... or ... declarations. The Ipa module is fully cached, and also provides conversions to and from DB instances when it makes sense (for types that are not derived IPA ones).
Class customization
This works more or less like before, with one notable exception: the overrideable property getters are now named getImmediateX in case the result is a class (not a built-in type), and are used to return the result without element resolution kicking in. For pure DB types, properties are implemented as before based on DB relations (using the property getters defined in Db.qll). For fresh or derived IPA types, properties are left unimplemented. Inherited properties will however be implemented if the type is a derived IPA with the source compatible with the inherited type.
Example
This PR contains a simple example of usage, introducing singleton IPA-synthesized unknown file and location instances.
Class fields
It was initially planned to have underlying DB entities or derived IPA constructor argumetns as fields in the classes. This turned out to not work because that would have required extensive use of characteristic predicates, which were exhausting the internal limit of 2^25 for BDD tree nodes...
Further work
This is a prototype with some corners being cut:
- IPA types are still used for
dbscheme,trapandcppgeneration, they should be removed from there qlgen.pyhas become too big and with too many things being generated, it should probably be split- while codegen unit tests have been kept passing, the additional functionality is not covered yet
- there is room for quality of life improvements, like generating getters for derived IPA type constructor arguments
getImmediateXmight be too noisy to have in the public interface of the classes. Maybe we can rethink the resolution mechanism that we have used mostly for hiding conversion AST nodes, or maybe we can just hide away this detail better. (aprotectedaccess modifier would help here...)