modulegraphs

Search:
Group by:
Source   Edit  

This module implements the module graph data structure. The module graph represents a complete Nim project. Single modules can either be kept in RAM or stored in a rod-file.

Types

Iface = object
  module*: PSym              ## module this "Iface" belongs to
  converters*: seq[PSym]
  patterns*: seq[PSym]
  pureEnums*: seq[PSym]
  uniqueName*: Rope
data we don't want to store directly in the ast.PSym type for s.kind == skModule Source   Edit  
ModuleGraph {.acyclic.} = ref object
  ifaces*: seq[Iface]        ## indexed by int32 fileIdx
  typeInstCache*: Table[ItemId, seq[PType]]
  procInstCache*: Table[ItemId, seq[PInstantiation]]
  attachedOps*: array[TTypeAttachedOp, Table[ItemId, PSym]]
  opsLog*: seq[LogEntry]
  methodsPerGenericType*: Table[ItemId, seq[(int, PSym)]]
  memberProcsPerType*: Table[ItemId, seq[PSym]]
  initializersPerType*: Table[ItemId, PNode]
  enumToStringProcs*: Table[ItemId, PSym]
  emittedTypeInfo*: Table[string, FileIndex]
  icCnifFiles*: seq[string]
  pendingMethodReplays*: seq[PSym]
  icImplDeps*: IntSet
  icQualIfaces*: IntSet
  inVMTransform*: int
  packageSyms*: TStrTable
  deps*: IntSet
  importDeps*: Table[FileIndex, seq[FileIndex]]
  suggestMode*: bool
  interactive*: bool
  withinSystem*: bool
  inclToMod*: Table[FileIndex, FileIndex]
  importStack*: seq[FileIndex]
  backend*: RootRef
  config*: ConfigRef
  cache*: IdentCache
  vm*: RootRef
  repl*: RootRef
  doStopCompile*: proc (): bool {.closure.}
  usageSym*: PSym
  owners*: seq[PSym]
  suggestSymbols*: SuggestSymbolDatabase
  suggestErrors*: Table[FileIndex, seq[Suggest]]
  methods*: seq[tuple[methods: seq[PSym], dispatcher: PSym]]
  bucketTable*: CountTable[ItemId]
  objectTree*: Table[ItemId, seq[tuple[depth: int, value: PType]]]
  methodsPerType*: Table[ItemId, seq[PSym]]
  dispatchers*: seq[PSym]
  systemModule*: PSym
  sysTypes*: array[TTypeKind, PType]
  compilerprocs*: TStrTable
  exposed*: TStrTable
  packageTypes*: TStrTable
  emptyNode*: PNode
  canonTypes*: Table[SigHash, PType]
  symBodyHashes*: Table[int, SigHash]
  importModuleCallback*: proc (graph: ModuleGraph; m: PSym; fileIdx: FileIndex): PSym {.
      nimcall.}
  includeFileCallback*: proc (graph: ModuleGraph; m: PSym; fileIdx: FileIndex): PNode {.
      nimcall.}
  cacheSeqs*: Table[string, PNode]
  cacheCounters*: Table[string, BiggestInt]
  cacheTables*: Table[string, BTree[string, PNode]]
  transitiveReplayActions*: seq[PNode]
  passes*: seq[TPass]
  pipelinePass*: PipelinePass
  onDefinition*: proc (graph: ModuleGraph; s: PSym; info: TLineInfo) {.nimcall.}
  onDefinitionResolveForward*: proc (graph: ModuleGraph; s: PSym;
                                     info: TLineInfo) {.nimcall.}
  onUsage*: proc (graph: ModuleGraph; s: PSym; info: TLineInfo) {.nimcall.}
  globalDestructors*: seq[PNode]
  strongSemCheck*: proc (graph: ModuleGraph; owner: PSym; body: PNode) {.nimcall.}
  compatibleProps*: proc (graph: ModuleGraph; formal, actual: PType): bool {.
      nimcall.}
  idgen*: IdGenerator
  operators*: Operators
  cachedFiles*: StringTableRef
  procGlobals*: seq[PNode]
  nifReplayActions*: Table[int32, seq[PNode]]
Source   Edit  
ModuleIter = object
Source   Edit  
Operators = object
  opNot*, opContains*, opLe*, opLt*, opAnd*, opOr*, opIsNil*, opEq*: PSym
  opAdd*, opSub*, opMul*, opDiv*, opLen*: PSym
Source   Edit  
PipelinePass = enum
  NonePass, SemPass, JSgenPass, CgenPass, NifgenPass, EvalPass, InterpreterPass,
  GenDependPass, Docgen2TexPass, Docgen2JsonPass, Docgen2Pass
Source   Edit  
SigHash = distinct MD5Digest
Source   Edit  
TPass = tuple[open: TPassOpen, process: TPassProcess, close: TPassClose,
              isFrontend: bool]
Source   Edit  
TPassClose = proc (graph: ModuleGraph; p: PPassContext; n: PNode): PNode {.
    nimcall.}
Source   Edit  
TPassContext = object of RootObj
  idgen*: IdGenerator
Source   Edit  
TPassOpen = proc (graph: ModuleGraph; module: PSym; idgen: IdGenerator): PPassContext {.
    nimcall.}
Source   Edit  
TPassProcess = proc (p: PPassContext; topLevelStmt: PNode): PNode {.nimcall.}
Source   Edit  

Consts

HookDisambBit = 0x20000000'i32
Set in the disamb of synthesized type-bound operators and $enum procs whose value is content-derived (see setHookDisamb); disjoint from both the small counter range and the InstanceDisambBit range. Source   Edit  
InstanceDisambBit = 0x40000000'i32
Set in the disamb of routine instances whose value is content-derived (see setInstanceDisamb); keeps them disjoint from the small counter range ordinary symbols draw from, so the NIF name name.disamb.module stays collision-free within a module. Source   Edit  

Procs

proc `$`(u: SigHash): string {....raises: [], tags: [], forbids: [].}
Source   Edit  
proc `==`(a, b: SigHash): bool {....raises: [], tags: [], forbids: [].}
Source   Edit  
proc addDep(g: ModuleGraph; m: PSym; dep: FileIndex) {.
    ...raises: [KeyError, ValueError, Exception, OSError],
    tags: [RootEffect, ReadEnvEffect, ReadIOEffect, ReadDirEffect], forbids: [].}
Source   Edit  
proc addDispatchers(g: ModuleGraph; value: PSym) {....raises: [], tags: [],
    forbids: [].}
Source   Edit  
proc addIncludeDep(g: ModuleGraph; module, includeFile: FileIndex) {....raises: [],
    tags: [], forbids: [].}
Source   Edit  
proc addMethodToGeneric(g: ModuleGraph; module: int; t: PType; col: int; m: PSym) {.
    ...raises: [Exception, KeyError, ValueError, OSError],
    tags: [RootEffect, ReadEnvEffect, ReadIOEffect, ReadDirEffect], forbids: [].}
Source   Edit  
proc addNifReplayAction(g: ModuleGraph; module: int32; n: PNode) {....raises: [],
    tags: [], forbids: [].}
Stores a replay action for NIF-based incremental compilation. Source   Edit  
proc belongsToStdlib(graph: ModuleGraph; sym: PSym): bool {.
    ...raises: [KeyError, ValueError, Exception, OSError],
    tags: [RootEffect, ReadEnvEffect, ReadIOEffect, ReadDirEffect], forbids: [].}
Check if symbol belongs to the 'stdlib' package. Source   Edit  
proc completePartialOp(g: ModuleGraph; module: int; t: PType;
                       op: TTypeAttachedOp; value: PSym) {.inline, ...raises: [],
    tags: [], forbids: [].}
Source   Edit  
proc configComplete(g: ModuleGraph) {....raises: [], tags: [], forbids: [].}
Source   Edit  
proc copyTypeProps(g: ModuleGraph; module: int; dest, src: PType) {.
    ...raises: [KeyError, Exception], tags: [RootEffect], forbids: [].}
Source   Edit  
proc createMagic(g: ModuleGraph; idgen: IdGenerator; name: string; m: TMagic): PSym {.
    ...raises: [KeyError, ValueError, Exception, OSError],
    tags: [RootEffect, ReadEnvEffect, ReadIOEffect, ReadDirEffect], forbids: [].}
Source   Edit  
proc fileSymbols(graph: ModuleGraph; fileIdx: FileIndex): SuggestFileSymbolDatabase {.
    ...raises: [], tags: [], forbids: [].}
Source   Edit  
proc flushMethodReplays(g: ModuleGraph) {.
    ...raises: [KeyError, ValueError, Exception, OSError],
    tags: [RootEffect, ReadEnvEffect, ReadIOEffect, ReadDirEffect], forbids: [].}
Builds the dispatch buckets from the method registrations collected during module loading; called once every module of the program is loaded (nifbackend.generateCode). Source   Edit  
proc getAttachedOp(g: ModuleGraph; t: PType; op: TTypeAttachedOp): PSym {.
    ...raises: [KeyError, Exception], tags: [RootEffect], forbids: [].}
returns the requested attached operation for type t. Can return nil if no such operation exists. Source   Edit  
proc getBody(g: ModuleGraph; s: PSym): PNode {.inline,
    ...raises: [KeyError, ValueError, Exception, OSError],
    tags: [RootEffect, ReadEnvEffect, ReadIOEffect, ReadDirEffect], forbids: [].}
Source   Edit  
proc getModule(g: ModuleGraph; fileIdx: FileIndex): PSym {....raises: [], tags: [],
    forbids: [].}
Source   Edit  
proc getPackage(graph: ModuleGraph; fileIdx: FileIndex): PSym {.
    ...raises: [KeyError], tags: [ReadDirEffect], forbids: [].}
Returns a package symbol for yet to be defined module for fileIdx. The package symbol is added to the graph if it doesn't exist. Source   Edit  
proc getToStringProc(g: ModuleGraph; t: PType): PSym {....raises: [Exception],
    tags: [RootEffect], forbids: [].}
Source   Edit  
proc hasDisabledAsgn(g: ModuleGraph; t: PType): bool {.
    ...raises: [KeyError, Exception, ValueError, OSError],
    tags: [RootEffect, ReadEnvEffect, ReadIOEffect, ReadDirEffect], forbids: [].}
Source   Edit  
proc hash(u: SigHash): Hash {....raises: [], tags: [], forbids: [].}
Source   Edit  
proc hash(x: FileIndex): Hash {.borrow, ...raises: [], tags: [], forbids: [].}
Source   Edit  
proc initModuleIter(mi: var ModuleIter; g: ModuleGraph; m: PSym; name: PIdent): PSym {.
    ...raises: [KeyError, ValueError, Exception, OSError],
    tags: [RootEffect, ReadEnvEffect, ReadIOEffect, ReadDirEffect], forbids: [].}
Source   Edit  
proc initOperators(g: ModuleGraph): Operators {.
    ...raises: [KeyError, ValueError, Exception, OSError],
    tags: [RootEffect, ReadEnvEffect, ReadIOEffect, ReadDirEffect], forbids: [].}
Source   Edit  
proc initStrTables(g: ModuleGraph; m: PSym) {.
    ...raises: [KeyError, ValueError, Exception, OSError],
    tags: [RootEffect, ReadEnvEffect, ReadIOEffect, ReadDirEffect], forbids: [].}
Source   Edit  
proc isCachedModule(g: ModuleGraph; m: PSym): bool {.inline,
    ...raises: [KeyError, ValueError, Exception, OSError],
    tags: [RootEffect, ReadEnvEffect, ReadIOEffect, ReadDirEffect], forbids: [].}
Source   Edit  
proc isDirty(g: ModuleGraph; m: PSym): bool {.
    ...raises: [KeyError, ValueError, Exception, OSError],
    tags: [RootEffect, ReadEnvEffect, ReadIOEffect, ReadDirEffect], forbids: [].}
Source   Edit  
proc loadCompilerProc(g: ModuleGraph; name: string): PSym {.
    ...raises: [OSError, ValueError, KeyError, Exception],
    tags: [ReadDirEffect, RootEffect, ReadEnvEffect, ReadIOEffect], forbids: [].}
Source   Edit  
proc logGenericInstance(g: ModuleGraph; inst: PSym) {....raises: [], tags: [],
    forbids: [].}
Log a generic instance so it gets written to the NIF file. This is needed when generic instances are created during compile-time evaluation and may be referenced from other modules compiled in the same run. Source   Edit  
proc logMethodDef(g: ModuleGraph; s: PSym) {....raises: [], tags: [], forbids: [].}
Log a method registration (cgmeth.methodDef) so that importers and the backend can rebuild the dispatch buckets (g.methods) from the NIF replay log — the serialized method ast carries its dispatcher sym at dispatcherPos, so replay reuses the original dispatcher that all call sites reference by name (see registerLoadedMethod). Source   Edit  
proc markClientsDirty(g: ModuleGraph; fileIdx: FileIndex) {....raises: [],
    tags: [], forbids: [].}
Source   Edit  
proc markDirty(g: ModuleGraph; fileIdx: FileIndex) {....raises: [], tags: [],
    forbids: [].}
Source   Edit  
proc moduleFromNifFile(g: ModuleGraph; fileIdx: FileIndex;
                       flags: set[LoadFlag] = {}): PrecompiledModule {.
    ...raises: [OSError, KeyError, ValueError, Exception],
    tags: [ReadDirEffect, RootEffect, ReadEnvEffect, ReadIOEffect], forbids: [].}
Returns 'nil' if the module needs to be recompiled. Loads module from NIF file when optCompress is enabled. When loadFullAst is true, loads the complete module AST for code generation. Source   Edit  
proc moduleOpenForCodegen(g: ModuleGraph; m: FileIndex): bool {.inline,
    ...raises: [], tags: [], forbids: [].}
Source   Edit  
proc needsCompilation(g: ModuleGraph): bool {.
    ...raises: [KeyError, ValueError, Exception, OSError],
    tags: [RootEffect, ReadEnvEffect, ReadIOEffect, ReadDirEffect], forbids: [].}
Source   Edit  
proc needsCompilation(g: ModuleGraph; fileIdx: FileIndex): bool {.
    ...raises: [KeyError, ValueError, Exception, OSError],
    tags: [RootEffect, ReadEnvEffect, ReadIOEffect, ReadDirEffect], forbids: [].}
Source   Edit  
proc needsIncludeScan(g: ModuleGraph; fileIdx: FileIndex): bool {....raises: [],
    tags: [], forbids: [].}
True when fileIdx is neither a known module of its own nor an already-known include file — i.e. a cold-opened file whose includer we must still discover via registerIncluderFromNif. Source   Edit  
proc newModuleGraph(cache: IdentCache; config: ConfigRef): ModuleGraph {.
    ...raises: [KeyError, ValueError, Exception, OSError],
    tags: [RootEffect, ReadEnvEffect, ReadIOEffect, ReadDirEffect], forbids: [].}
Source   Edit  
proc nextModuleIter(mi: var ModuleIter; g: ModuleGraph): PSym {....raises: [],
    tags: [], forbids: [].}
Source   Edit  
proc onProcessing(graph: ModuleGraph; fileIdx: FileIndex; moduleStatus: string;
                  fromModule: PSym) {....raises: [ValueError, OSError, KeyError,
    Exception, IOError, ERecoverableError], tags: [RootEffect, ReadDirEffect,
    WriteIOEffect, ReadIOEffect, ReadEnvEffect], forbids: [].}
Source   Edit  
proc parentModule(g: ModuleGraph; fileIdx: FileIndex): FileIndex {....raises: [],
    tags: [], forbids: [].}
returns 'fileIdx' if the file belonging to this index is directly used as a module or else the module that first references this include file. Source   Edit  
proc recordIcImplDep(g: ModuleGraph; s: PSym) {.
    ...raises: [KeyError, ValueError, Exception, OSError],
    tags: [RootEffect, ReadEnvEffect, ReadIOEffect, ReadDirEffect], forbids: [].}
NeedsImpl edge tracking, see icImplDeps. Called from the compile-time body consumption sites (vmgen's proc compilation, the getImpl opcodes). Own-module and group-member entries are filtered out when the .edges sidecar is written. Source   Edit  
proc reexportedModuleSyms(g: ModuleGraph; m: PSym): seq[(string, string)] {.
    ...raises: [KeyError, ValueError, Exception, OSError],
    tags: [RootEffect, ReadEnvEffect, ReadIOEffect, ReadDirEffect], forbids: [].}
(name, NIF module suffix) of MODULE syms in m's interface — these are re-exports (import x; export x, added by reexportSym) acting as qualifiers (m.x.sym). Consumed by the NIF writer; semExport does not put them into the nkExportStmt children, so the AST walk cannot see them. Source   Edit  
proc registerIncluderFromNif(g: ModuleGraph; fileIdx: FileIndex): bool {.
    ...raises: [OSError, ValueError, Exception, KeyError],
    tags: [ReadEnvEffect, ReadIOEffect, ReadDirEffect, RootEffect], forbids: [].}

Targeted cold-include discovery for nimsuggest: scan the nimcache NIFs (scanIncludeGraph) for a module whose include-set contains this file and register only that single include->module edge in inclToMod, so a query inside the include file resolves its includer via parentModule.

Deliberately targeted: registering every include relationship (i.e. also system's own includes) eagerly assigns FileIndexes and pollutes inclToMod, which perturbs the NIF line-info decode of unrelated modules (system.string then resolves into excpt.nim). Touch nothing but the one edge we need.

Source   Edit  
proc registerLoadedMethod(g: ModuleGraph; m: PSym) {.
    ...raises: [KeyError, ValueError, Exception, OSError],
    tags: [RootEffect, ReadEnvEffect, ReadIOEffect, ReadDirEffect], forbids: [].}
Rebuild the dispatch buckets from a serialized method registration. Buckets group the methods sharing a dispatcher; the dispatcher's BODY does not exist in serialized form — generateIfMethodDispatchers synthesizes it in the backend from the complete bucket. Source   Edit  
proc registerModule(g: ModuleGraph; m: PSym) {.
    ...raises: [KeyError, ValueError, Exception, OSError],
    tags: [RootEffect, ReadEnvEffect, ReadIOEffect, ReadDirEffect], forbids: [].}
Source   Edit  
proc registerModuleById(g: ModuleGraph; m: FileIndex) {.
    ...raises: [KeyError, ValueError, Exception, OSError],
    tags: [RootEffect, ReadEnvEffect, ReadIOEffect, ReadDirEffect], forbids: [].}
Source   Edit  
proc resetAllModules(g: ModuleGraph) {....raises: [KeyError, ValueError, Exception,
    OSError], tags: [RootEffect, ReadEnvEffect, ReadIOEffect, ReadDirEffect],
                                       forbids: [].}
Source   Edit  
proc resetForBackend(g: ModuleGraph) {....raises: [], tags: [], forbids: [].}
Source   Edit  
proc setAttachedOp(g: ModuleGraph; module: int; t: PType; op: TTypeAttachedOp;
                   value: PSym) {....raises: [Exception], tags: [RootEffect],
                                  forbids: [].}
we also need to record this to the packed module. Source   Edit  
proc setAttachedOp(g: ModuleGraph; module: int; typeId: ItemId;
                   op: TTypeAttachedOp; value: PSym) {....raises: [], tags: [],
    forbids: [].}
Overload that takes ItemId directly, useful for registering hooks from NIF index. Source   Edit  
proc setAttachedOpPartial(g: ModuleGraph; module: int; t: PType;
                          op: TTypeAttachedOp; value: PSym) {....raises: [],
    tags: [], forbids: [].}
we also need to record this to the packed module. Source   Edit  
proc setHookDisamb(g: ModuleGraph; hook: PSym; opName: string; typ: PType) {.
    ...raises: [Exception, KeyError], tags: [RootEffect], forbids: [].}
Under IC, replace a synthesized hook's counter-based disamb with a content-derived one: a hash of the operation name plus the typeKey of the type it is bound to. Counter disambs renumber whenever an earlier hook appears in a re-semmed module, so cached translation units keep calling the old _u<disamb> C name while the regenerated producer defines a new one — the hook flavor of the backend def-migration hole. With a content-derived value the hook's NIF name (and hence its C name) is stable as long as the type itself is unchanged. Source   Edit  
proc setInstanceDisamb(g: ModuleGraph; inst, generic: PSym;
                       concreteTypes: openArray[PType]) {.
    ...raises: [Exception, KeyError], tags: [RootEffect], forbids: [].}
Under IC, replace a fresh routine instance's counter-based disamb with a content-derived one: a hash of the generic's identity plus the typeKey of every concrete type argument — exactly the identity the instantiation cache compares. The instance's NIF name name.disamb.modsuffix then differs only in the module suffix when the same instantiation is made by different modules, which is the prerequisite for cross-module generic-instance merging (and gives the dce analysis its offers keys). The hash is computed once, here; it is never recomputed — the value travels in the serialized disamb field. Source   Edit  
proc setMethodsPerType(g: ModuleGraph; id: ItemId; methods: seq[PSym]) {.
    ...raises: [], tags: [], forbids: [].}
Source   Edit  
proc setToStringProc(g: ModuleGraph; t: PType; value: PSym) {.
    ...raises: [Exception], tags: [RootEffect], forbids: [].}
Source   Edit  
proc someSym(g: ModuleGraph; m: PSym; name: PIdent): PSym {.
    ...raises: [KeyError, ValueError, Exception, OSError],
    tags: [RootEffect, ReadEnvEffect, ReadIOEffect, ReadDirEffect], forbids: [].}
Source   Edit  
proc someSymAmb(g: ModuleGraph; m: PSym; name: PIdent; amb: var bool): PSym {.
    ...raises: [KeyError, ValueError, Exception, OSError],
    tags: [RootEffect, ReadEnvEffect, ReadIOEffect, ReadDirEffect], forbids: [].}
Source   Edit  
proc stopCompile(g: ModuleGraph): bool {.inline, ...raises: [Exception],
    tags: [RootEffect], forbids: [].}
Source   Edit  
proc strTableAdds(g: ModuleGraph; m: PSym; s: PSym) {.
    ...raises: [KeyError, ValueError, Exception, OSError],
    tags: [RootEffect, ReadEnvEffect, ReadIOEffect, ReadDirEffect], forbids: [].}
Source   Edit  
proc systemModuleSym(g: ModuleGraph; name: PIdent): PSym {.
    ...raises: [KeyError, ValueError, Exception, OSError],
    tags: [RootEffect, ReadEnvEffect, ReadIOEffect, ReadDirEffect], forbids: [].}
Source   Edit  
proc uniqueModuleName(conf: ConfigRef; m: PSym): string {.
    ...raises: [KeyError, ValueError, Exception, OSError],
    tags: [RootEffect, ReadEnvEffect, ReadIOEffect, ReadDirEffect], forbids: [].}
The unique module name is guaranteed to only contain {'A'..'Z', 'a'..'z', '0'..'9', '_'} so that it is useful as a C identifier snippet. Source   Edit  
proc unmarkAllDirty(g: ModuleGraph) {....raises: [], tags: [], forbids: [].}
Source   Edit  

Iterators

iterator allSyms(g: ModuleGraph; m: PSym): PSym {.
    ...raises: [KeyError, ValueError, Exception, OSError],
    tags: [RootEffect, ReadEnvEffect, ReadIOEffect, ReadDirEffect], forbids: [].}
Source   Edit  
iterator getDispatchers(g: ModuleGraph): PSym {....raises: [], tags: [],
    forbids: [].}
Source   Edit  
iterator getMethodsPerType(g: ModuleGraph; t: PType): PSym {....raises: [KeyError],
    tags: [], forbids: [].}
Source   Edit  
iterator methodsForGeneric(g: ModuleGraph; t: PType): (int, PSym) {.
    ...raises: [KeyError], tags: [], forbids: [].}
Source   Edit  
iterator procInstCacheItems(g: ModuleGraph; s: PSym): PInstantiation {.
    ...raises: [KeyError], tags: [], forbids: [].}
Source   Edit  
iterator suggestErrorsIter(g: ModuleGraph): Suggest {....raises: [], tags: [],
    forbids: [].}
Source   Edit  
iterator suggestSymbolsIter(g: ModuleGraph): SymInfoPair {....raises: [], tags: [],
    forbids: [].}
Source   Edit  
iterator systemModuleSyms(g: ModuleGraph; name: PIdent): PSym {.
    ...raises: [KeyError, ValueError, Exception, OSError],
    tags: [RootEffect, ReadEnvEffect, ReadIOEffect, ReadDirEffect], forbids: [].}
Source   Edit  
iterator typeInstCacheItems(g: ModuleGraph; s: PSym): PType {.
    ...raises: [KeyError], tags: [], forbids: [].}
Source   Edit  

Templates

template onDef(info: TLineInfo; s: PSym)
Source   Edit  
template onDefResolveForward(info: TLineInfo; s: PSym)
Source   Edit  
template onUse(info: TLineInfo; s: PSym; isGenericInstance = false)
Source   Edit  
template semtabAll(g: ModuleGraph; m: PSym): TStrTable
Source   Edit