compiler/mir/mirtypes

    Dark Mode
Search:
  Source   Edit

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

FieldId = distinct uint32
  Source   Edit
HeaderId = uint32
  Source   Edit
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
ParamFlag = enum
  pfByRef
  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
TypeKind = enum
  tkVoid, tkBool, tkChar, tkInt, tkUInt, tkFloat, tkPointer, tkPtr, tkRef,
  tkVar, tkLent, tkProc, tkClosure, ## proc + environment
  tkArray, tkUncheckedArray, tkOpenArray, tkSet, tkSeq, tkString, tkCstring,
  tkImported, tkIndirect, tkRecord, tkUnion, tkTaggedUnion
  Source   Edit
TypeSym = object
  inst*: PType               ## the original type instance
  canon*: TypeId             ## if a type symbol is the canonical one, canon points to itself
  desc*: array[Level, HeaderId]
A type symbol links together the various representations of a type.   Source   Edit

Consts

BoolType = 1'u32
  Source   Edit
CharType = 2'u32
  Source   Edit
CstringType = 14'u32
  Source   Edit
Float32Type = 11'u32
  Source   Edit
Float64Type = 12'u32
  Source   Edit
Int8Type = 3'u32
  Source   Edit
Int16Type = 4'u32
  Source   Edit
Int32Type = 5'u32
  Source   Edit
Int64Type = 6'u32
  Source   Edit
PointerType = 15'u32
  Source   Edit
StringType = 13'u32
  Source   Edit
UInt8Type = 7'u32
  Source   Edit
UInt16Type = 8'u32
  Source   Edit
UInt32Type = 9'u32
  Source   Edit
UInt64Type = 10'u32
  Source   Edit
VoidType = 0'u32
  Source   Edit

Procs

func `==`(a, b: FieldId): bool {.borrow, inline, ...raises: [], tags: [].}
  Source   Edit
func `[]`(env: TypeEnv; id: HeaderId): lent TypeHeader {.inline, inline,
    ...raises: [], tags: [].}
  Source   Edit
func `[]`(env: TypeEnv; id: TypeId): lent PType {.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 bitsize(f: RecField): int {.inline, ...raises: [], tags: [].}
  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 get(env: TypeEnv; id: TypeId): lent TypeSym {....raises: [], tags: [].}
  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 isNamed(f: RecField): bool {.inline, ...raises: [], tags: [].}
  Source   Edit
func isNoAlias(f: RecField): bool {.inline, ...raises: [], tags: [].}
  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
func name(env: TypeEnv; f: RecField): lent string {.inline, ...raises: [], tags: [].}
  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
func sizeType(env: TypeEnv): TypeId {.inline, ...raises: [], tags: [].}
Returns the type to use for values representing some size. This is a signed integer type of target-dependent bit-width.   Source   Edit
func usizeType(env: TypeEnv): TypeId {.inline, ...raises: [], tags: [].}
Returns the type to use for values representing some size. This is an unsigned integer type of target-dependent bit-width.   Source   Edit

Iterators

iterator fields(env: TypeEnv; desc: TypeHeader; offset = 0): (FieldId, RecField) {.
    ...raises: [], tags: [].}
Returns all fields directly part of desc. Super types are not considered.   Source   Edit
iterator params(env: TypeEnv; desc: TypeHeader): tuple[i: int, typ: TypeId,
    flags: set[ParamFlag]] {.inline, ...raises: [], tags: [].}
Returns the typ and flags for all parameters of type t   Source   Edit

Templates

template `[]`(env: TypeEnv; id: FieldId): RecField
  Source   Edit
template `[]`(env: TypeEnv; t: PType): TypeId
  Source   Edit
template buildProc(env: var TypeEnv; kind: TypeKind; conv: TCallingConvention;
                   ret: TypeId; builder, body: untyped): TypeId
Convenience template for a structured way of producing type descriptions.   Source   Edit