Implements the type IR for the MIR phase (not yet), plus the TypeEnv, which stores the data for all types.
All types are addressed via TypeId, with the built-in types using static IDs. Every TypeId is associated with a TypeSym, linking together the type's various representations. If multiple equal structural types are added to the environment, the one added first is designated as the "canonical" one.
At the MIR level, a type representation has three different levels (Level). On the Original level, all type references are exactly as they appear in the PType form, the Canonical level only uses references to canonical types, and the Lowered level is the type as the code generator sees it.
Types
Level = enum Original, ## contains the original type symbols Canonical, ## same as `Original`, but with only canonical types symbols Lowered ## fully lowered version of the type
- Source Edit
ProcBuilder = object header: TypeHeader params: seq[tuple[x: uint32, typ: TypeId]]
- Source Edit
RecField = object ident: LitId offset: IntVal align*: int16 extra: uint16 typ*: TypeId
- Record field description. Source Edit
TypeEnv = object map: TypeTable[TypeId] symbols {.requiresInit.}: Store[TypeId, TypeSym] headers: Store[HeaderId, TypeHeader] ## all type headers fields: seq[RecField] ## all record fields referenced from `headers` params: seq[tuple[x: uint32, typ: TypeId]] ## all parameters referenced from `headers` structs: seq[uint32] ## an open-addressing using hash table. Indexed by ``hash(desc)``. The ## items are indices (biased by 1) into the `headers` sequence numStructs: int ## the number of occupied slots in `structs` canon: Table[HeaderId, TypeId] ## maps headers of canonical type descriptions to their type symbol instances: Table[SigHash, TypeId] ## associates the sighash of a generic type instance with a type symbol. ## This is used for eliminating same-shaped instantiations of a generic ## object type idents: BiTable[string] numbers: BiTable[BiggestInt] config: ConfigRef graph: ModuleGraph sizeType: TypeId ## the target-dependent integer type to use for size values usizeType: TypeId ## the target-dependent unsigned integer type to use for size values
- Stores the data associated with types. Has no valid default value, and must be explicitly initialized first. Source Edit
TypeHeader = object kind*: TypeKind align*: int16 ## required alignment size: IntVal ## size in bytes a: uint32 ## meaning depends on the type b: uint32 ## meaning depends on the type
- Type description header. Source Edit
Consts
CstringType = 14'u32
- Source Edit
Float32Type = 11'u32
- Source Edit
Float64Type = 12'u32
- Source Edit
PointerType = 15'u32
- Source Edit
StringType = 13'u32
- Source Edit
UInt16Type = 8'u32
- Source Edit
UInt32Type = 9'u32
- Source Edit
UInt64Type = 10'u32
- Source Edit
Procs
func `[]`(env: TypeEnv; id: HeaderId): lent TypeHeader {.inline, inline, ...raises: [], tags: [].}
- Source Edit
proc add(env: var TypeEnv; t: PType): TypeId {. ...raises: [Exception, ERecoverableError, KeyError], tags: [RootEffect, ReadDirEffect].}
- If not registered yet, adds t to env and returns the ID to later look it up with. Source Edit
proc addParam(b: var ProcBuilder; s: set[ParamFlag]; typ: TypeId) {....raises: [], tags: [].}
- Adds a parameter to the proc type. Source Edit
proc arrayLen(desc: TypeHeader; env: TypeEnv): BiggestInt {.inline, inline, ...raises: [], tags: [].}
- Source Edit
func base(desc: TypeHeader; env: TypeEnv): TypeId {.inline, ...raises: [], tags: [].}
- Returns the node storing the base type (i.e., the parent type) for a record type. Source Edit
func callConv(desc: TypeHeader; env: TypeEnv): TCallingConvention {.inline, ...raises: [], tags: [].}
- Source Edit
proc canonical(env: TypeEnv; typ: TypeId): TypeId {....raises: [], tags: [].}
- Returns the canonical symbol for typ. All indirections are skipped. Source Edit
proc computeDepth(env: TypeEnv; desc: TypeHeader; pos: int32): int {....raises: [], tags: [].}
- Computes the depth at which the field with position pos is located. 0 means it's part of desc, 1 means it's part of the first parent type, etc. Source Edit
proc count(desc: TypeHeader): uint32 {.inline, inline, ...raises: [], tags: [].}
- Returns the number of elements the set type can contain. Source Edit
func discr(desc: TypeHeader; env: TypeEnv): FieldId {.inline, ...raises: [], tags: [].}
- Returns the discriminator field for the given tagged union. Source Edit
proc elem(desc: TypeHeader): TypeId {.inline, inline, ...raises: [], tags: [].}
- Returns the element type for h. Source Edit
func fieldOffset(desc: TypeHeader; env: TypeEnv): int32 {.inline, ...raises: [], tags: [].}
- Returns the first field's position in the object. Source Edit
func hasVarargs(desc: TypeHeader; env: TypeEnv): bool {.inline, ...raises: [], tags: [].}
- Source Edit
func headerFor(env: TypeEnv; id: TypeId; phase: Level): lent TypeHeader {. inline, ...raises: [], tags: [].}
- Source Edit
proc initTypeEnv(graph: ModuleGraph): TypeEnv {. ...raises: [KeyError, Exception, ERecoverableError], tags: [ReadDirEffect, RootEffect].}
- Returns a fully initialized type environment instance. Source Edit
proc isEmbedded(env: TypeEnv; typ: TypeId): bool {....raises: [], tags: [].}
- Whether the typ is a record that's directly embedded where it's used. Source Edit
func isNoMangle(f: RecField): bool {.inline, ...raises: [], tags: [].}
- Whether the field's name must not be mangled. Source Edit
func isPacked(desc: TypeHeader; env: TypeEnv): bool {.inline, ...raises: [], tags: [].}
- Whether the record type is Source Edit
proc lookupField(env: TypeEnv; typ: TypeId; pos: int32): FieldId {....raises: [], tags: [].}
- Returns the ID of the field with position pos. Said field must exist in record-like type typ. Imported types and indirection are skipped. Source Edit
proc newType(env: var TypeEnv; desc: HeaderId): TypeId {....raises: [], tags: [].}
- If none exists already, creates a new type symbol for desc. Source Edit
func numFields(desc: TypeHeader): int {.inline, ...raises: [], tags: [].}
- Returns the number of fields in the record-like type, ignoring parent types. Source Edit
func numParams(desc: TypeHeader): int {.inline, ...raises: [], tags: [].}
- Source Edit
func retType(desc: TypeHeader; env: TypeEnv): TypeId {.inline, ...raises: [], tags: [].}
- Source Edit
func size(desc: TypeHeader; env: TypeEnv): BiggestInt {.inline, inline, ...raises: [], tags: [].}
- Returns the size-in-bytes for the given type. Source Edit