# # # The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # ## This module implements the passes functionality. A pass must implement the ## `TPass` interface. import options, ast, llstream, msgs, idents, syntaxes, idgen, modulegraphs, reorder, rod, lineinfos, pathutils type TPassData* = tuple[input: PNode, closeOutput: PNode] # a pass is a tuple of procedure vars ``TPass.close`` may produce additional # nodes. These are passed to the other close procedures. # This mechanism used to be used for the instantiation of generics. proc makePass*(open: TPassOpen = nil, process: TPassProcess = nil, close: TPassClose = nil, isFrontend = false): TPass = result.open = open result.close = close result.process = process result.isFrontend = isFrontend proc skipCodegen*(config: ConfigRef; n: PNode): bool {.inline.} = # can be used by codegen passes to determine whether they should do # something with `n`. Currently, this ignores `n` and uses the global # error count instead. result = config.errorCounter > 0 const maxPasses = 10 type TPassContextArray = array[0..maxPasses - 1, PPassContext] proc clearPasses*(g: ModuleGraph) = g.passes.setLen(0) proc registerPass*(g: ModuleGraph; p: TPass) = internalAssert g.config, g.passes.len < maxPasses g.passes.add(p) proc carryPass*(g: ModuleGraph; p: TPass, module: PSym; m: TPassData): TPassData = var c = p.open(g, module) result.input = p.process(c, m.input) result.closeOutput = if p.close != nil: p.close(g, c, m.closeOutput) else: m.closeOutput proc carryPasses*(g: ModuleGraph; nodes: PNode, module: PSym; passes: openArray[TPass]) = var passdata: TPassData passdata.input = nodes for pass in passes: passdata = carryPass(g, pass, module, passdata) proc openPasses(g: ModuleGraph; a: var TPassContextArray; module: PSym) = for i in 0..= 0 or isDefined(graph.config, "nimBackendAssumesChange") proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream): bool {.discardable.} = if graph.stopCompile(): return true var p: TParsers a: TPassContextArray s: PLLStream fileIdx = module.fileIdx prepareConfigNotes(graph, module) if module.id < 0: # new module caching mechanism: for i in 0..