summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2015-03-08 13:05:44 +0100
committerAraq <rumpf_a@web.de>2015-03-08 13:08:19 +0100
commitc40aac8e2036924ec88bec9c44a33a044f346baa (patch)
tree50dcee9d2224ed20f7773979a26679e4844cb49d /compiler
parente390d8ec4aa11571411b1e87ba7d163dd3501f8e (diff)
downloadNim-c40aac8e2036924ec88bec9c44a33a044f346baa.tar.gz
GC: get rid of pathological behaviour for stack marking
Diffstat (limited to 'compiler')
-rw-r--r--compiler/passes.nim98
-rw-r--r--compiler/transf.nim264
2 files changed, 181 insertions, 181 deletions
diff --git a/compiler/passes.nim b/compiler/passes.nim
index 96088bd88..129d8ad47 100644
--- a/compiler/passes.nim
+++ b/compiler/passes.nim
@@ -10,15 +10,15 @@
 # This module implements the passes functionality. A pass must implement the
 # `TPass` interface.
 
-import 
-  strutils, lists, options, ast, astalgo, llstream, msgs, platform, os, 
-  condsyms, idents, renderer, types, extccomp, math, magicsys, nversion, 
+import
+  strutils, lists, options, ast, astalgo, llstream, msgs, platform, os,
+  condsyms, idents, renderer, types, extccomp, math, magicsys, nversion,
   nimsets, syntaxes, times, rodread, idgen
 
-type  
+type
   TPassContext* = object of RootObj # the pass's context
     fromCache*: bool  # true if created by "openCached"
-   
+
   PPassContext* = ref TPassContext
 
   TPassOpen* = proc (module: PSym): PPassContext {.nimcall.}
@@ -33,8 +33,8 @@ type
   TPassData* = tuple[input: PNode, closeOutput: PNode]
   TPasses* = openArray[TPass]
 
-# a pass is a tuple of procedure vars ``TPass.close`` may produce additional 
-# nodes. These are passed to the other close procedures. 
+# 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,
@@ -53,46 +53,46 @@ proc makePass*(open: TPassOpen = nil,
 proc processModule*(module: PSym, stream: PLLStream, rd: PRodReader)
 
 # the semantic checker needs these:
-var 
+var
   gImportModule*: proc (m: PSym, fileIdx: int32): PSym {.nimcall.}
   gIncludeFile*: proc (m: PSym, fileIdx: int32): PNode {.nimcall.}
 
 # implementation
 
-proc skipCodegen*(n: PNode): bool {.inline.} = 
-  # can be used by codegen passes to determine whether they should do 
+proc skipCodegen*(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 = msgs.gErrorCounter > 0
 
-proc astNeeded*(s: PSym): bool = 
+proc astNeeded*(s: PSym): bool =
   # The ``rodwrite`` module uses this to determine if the body of a proc
   # needs to be stored. The passes manager frees s.sons[codePos] when
   # appropriate to free the procedure body's memory. This is important
   # to keep memory usage down.
   if (s.kind in {skMethod, skProc}) and
       ({sfCompilerProc, sfCompileTime} * s.flags == {}) and
-      (s.typ.callConv != ccInline) and 
-      (s.ast.sons[genericParamsPos].kind == nkEmpty): 
+      (s.typ.callConv != ccInline) and
+      (s.ast.sons[genericParamsPos].kind == nkEmpty):
     result = false
     # XXX this doesn't really make sense with excessive CTFE
   else:
     result = true
-  
-const 
+
+const
   maxPasses = 10
 
-type 
+type
   TPassContextArray = array[0..maxPasses - 1, PPassContext]
 
-var 
+var
   gPasses: array[0..maxPasses - 1, TPass]
   gPassesLen*: int
 
 proc clearPasses* =
   gPassesLen = 0
 
-proc registerPass*(p: TPass) = 
+proc registerPass*(p: TPass) =
   gPasses[gPassesLen] = p
   inc(gPassesLen)
 
@@ -109,48 +109,48 @@ proc carryPasses*(nodes: PNode, module: PSym, passes: TPasses) =
     passdata = carryPass(pass, module, passdata)
 
 proc openPasses(a: var TPassContextArray, module: PSym) =
-  for i in countup(0, gPassesLen - 1): 
-    if not isNil(gPasses[i].open): 
+  for i in countup(0, gPassesLen - 1):
+    if not isNil(gPasses[i].open):
       a[i] = gPasses[i].open(module)
     else: a[i] = nil
-  
+
 proc openPassesCached(a: var TPassContextArray, module: PSym, rd: PRodReader) =
-  for i in countup(0, gPassesLen - 1): 
-    if not isNil(gPasses[i].openCached): 
+  for i in countup(0, gPassesLen - 1):
+    if not isNil(gPasses[i].openCached):
       a[i] = gPasses[i].openCached(module, rd)
-      if a[i] != nil: 
+      if a[i] != nil:
         a[i].fromCache = true
     else:
       a[i] = nil
-  
-proc closePasses(a: var TPassContextArray) = 
+
+proc closePasses(a: var TPassContextArray) =
   var m: PNode = nil
-  for i in countup(0, gPassesLen - 1): 
+  for i in countup(0, gPassesLen - 1):
     if not isNil(gPasses[i].close): m = gPasses[i].close(a[i], m)
     a[i] = nil                # free the memory here
-  
-proc processTopLevelStmt(n: PNode, a: var TPassContextArray): bool = 
+
+proc processTopLevelStmt(n: PNode, a: var TPassContextArray): bool =
   # this implements the code transformation pipeline
   var m = n
-  for i in countup(0, gPassesLen - 1): 
-    if not isNil(gPasses[i].process): 
+  for i in countup(0, gPassesLen - 1):
+    if not isNil(gPasses[i].process):
       m = gPasses[i].process(a[i], m)
       if isNil(m): return false
   result = true
-  
-proc processTopLevelStmtCached(n: PNode, a: var TPassContextArray) = 
+
+proc processTopLevelStmtCached(n: PNode, a: var TPassContextArray) =
   # this implements the code transformation pipeline
   var m = n
-  for i in countup(0, gPassesLen - 1): 
+  for i in countup(0, gPassesLen - 1):
     if not isNil(gPasses[i].openCached): m = gPasses[i].process(a[i], m)
-  
-proc closePassesCached(a: var TPassContextArray) = 
+
+proc closePassesCached(a: var TPassContextArray) =
   var m: PNode = nil
-  for i in countup(0, gPassesLen - 1): 
-    if not isNil(gPasses[i].openCached) and not isNil(gPasses[i].close): 
+  for i in countup(0, gPassesLen - 1):
+    if not isNil(gPasses[i].openCached) and not isNil(gPasses[i].close):
       m = gPasses[i].close(a[i], m)
     a[i] = nil                # free the memory here
-  
+
 proc processImplicits(implicits: seq[string], nodeKind: TNodeKind,
                       a: var TPassContextArray) =
   for module in items(implicits):
@@ -159,45 +159,45 @@ proc processImplicits(implicits: seq[string], nodeKind: TNodeKind,
     str.info = gCmdLineInfo
     importStmt.addSon str
     if not processTopLevelStmt(importStmt, a): break
-  
+
 proc processModule(module: PSym, stream: PLLStream, rd: PRodReader) =
-  var 
+  var
     p: TParsers
     a: TPassContextArray
     s: PLLStream
     fileIdx = module.fileIdx
-  if rd == nil: 
+  if rd == nil:
     openPasses(a, module)
-    if stream == nil: 
+    if stream == nil:
       let filename = fileIdx.toFullPathConsiderDirty
       if module.name.s == "-":
         module.name.s = "stdinfile"
         s = llStreamOpen(stdin)
       else:
         s = llStreamOpen(filename, fmRead)
-      if s == nil: 
+      if s == nil:
         rawMessage(errCannotOpenFile, filename)
         return
     else:
       s = stream
-    while true: 
+    while true:
       openParsers(p, fileIdx, s)
 
       if sfSystemModule notin module.flags:
-        # XXX what about caching? no processing then? what if I change the 
+        # XXX what about caching? no processing then? what if I change the
         # modules to include between compilation runs? we'd need to track that
         # in ROD files. I think we should enable this feature only
         # for the interactive mode.
         processImplicits implicitImports, nkImportStmt, a
         processImplicits implicitIncludes, nkIncludeStmt, a
 
-      while true: 
+      while true:
         var n = parseTopLevelStmt(p)
-        if n.kind == nkEmpty: break 
+        if n.kind == nkEmpty: break
         if not processTopLevelStmt(n, a): break
 
       closeParsers(p)
-      if s.kind != llsStdIn: break 
+      if s.kind != llsStdIn: break
     closePasses(a)
     # id synchronization point for more consistent code generation:
     idSynchronizationPoint(1000)
diff --git a/compiler/transf.nim b/compiler/transf.nim
index 2f520aa20..e5e3bbe63 100644
--- a/compiler/transf.nim
+++ b/compiler/transf.nim
@@ -17,27 +17,27 @@
 # * introduces method dispatchers
 # * performs lambda lifting for closure support
 
-import 
-  intsets, strutils, lists, options, ast, astalgo, trees, treetab, msgs, os, 
+import
+  intsets, strutils, lists, options, ast, astalgo, trees, treetab, msgs, os,
   idents, renderer, types, passes, semfold, magicsys, cgmeth, rodread,
   lambdalifting, sempass2, lowerings
 
 # implementation
 
-type 
+type
   PTransNode* = distinct PNode
-  
+
   PTransCon = ref TTransCon
   TTransCon{.final.} = object # part of TContext; stackable
     mapping: TIdNodeTable     # mapping from symbols to nodes
     owner: PSym               # current owner
     forStmt: PNode            # current for stmt
-    forLoopBody: PTransNode   # transformed for loop body 
-    yieldStmts: int           # we count the number of yield statements, 
+    forLoopBody: PTransNode   # transformed for loop body
+    yieldStmts: int           # we count the number of yield statements,
                               # because we need to introduce new variables
                               # if we encounter the 2nd yield statement
     next: PTransCon           # for stacking
-  
+
   TTransfContext = object of passes.TPassContext
     module: PSym
     transCon: PTransCon      # top of a TransCon stack
@@ -46,52 +46,52 @@ type
     contSyms, breakSyms: seq[PSym]  # to transform 'continue' and 'break'
   PTransf = ref TTransfContext
 
-proc newTransNode(a: PNode): PTransNode {.inline.} = 
+proc newTransNode(a: PNode): PTransNode {.inline.} =
   result = PTransNode(shallowCopy(a))
 
-proc newTransNode(kind: TNodeKind, info: TLineInfo, 
-                  sons: int): PTransNode {.inline.} = 
+proc newTransNode(kind: TNodeKind, info: TLineInfo,
+                  sons: int): PTransNode {.inline.} =
   var x = newNodeI(kind, info)
   newSeq(x.sons, sons)
   result = x.PTransNode
 
-proc newTransNode(kind: TNodeKind, n: PNode, 
-                  sons: int): PTransNode {.inline.} = 
+proc newTransNode(kind: TNodeKind, n: PNode,
+                  sons: int): PTransNode {.inline.} =
   var x = newNodeIT(kind, n.info, n.typ)
   newSeq(x.sons, sons)
   x.typ = n.typ
   result = x.PTransNode
 
-proc `[]=`(a: PTransNode, i: int, x: PTransNode) {.inline.} = 
+proc `[]=`(a: PTransNode, i: int, x: PTransNode) {.inline.} =
   var n = PNode(a)
   n.sons[i] = PNode(x)
 
-proc `[]`(a: PTransNode, i: int): PTransNode {.inline.} = 
+proc `[]`(a: PTransNode, i: int): PTransNode {.inline.} =
   var n = PNode(a)
   result = n.sons[i].PTransNode
-  
+
 proc add(a, b: PTransNode) {.inline.} = addSon(PNode(a), PNode(b))
 proc len(a: PTransNode): int {.inline.} = result = sonsLen(a.PNode)
 
-proc newTransCon(owner: PSym): PTransCon = 
+proc newTransCon(owner: PSym): PTransCon =
   assert owner != nil
   new(result)
   initIdNodeTable(result.mapping)
   result.owner = owner
 
-proc pushTransCon(c: PTransf, t: PTransCon) = 
+proc pushTransCon(c: PTransf, t: PTransCon) =
   t.next = c.transCon
   c.transCon = t
 
-proc popTransCon(c: PTransf) = 
+proc popTransCon(c: PTransf) =
   if (c.transCon == nil): internalError("popTransCon")
   c.transCon = c.transCon.next
 
-proc getCurrOwner(c: PTransf): PSym = 
+proc getCurrOwner(c: PTransf): PSym =
   if c.transCon != nil: result = c.transCon.owner
   else: result = c.module
-  
-proc newTemp(c: PTransf, typ: PType, info: TLineInfo): PSym = 
+
+proc newTemp(c: PTransf, typ: PType, info: TLineInfo): PSym =
   result = newSym(skTemp, getIdent(genPrefix), getCurrOwner(c), info)
   result.typ = skipTypes(typ, {tyGenericInst})
   incl(result.flags, sfFromGeneric)
@@ -100,10 +100,10 @@ proc transform(c: PTransf, n: PNode): PTransNode
 
 proc transformSons(c: PTransf, n: PNode): PTransNode =
   result = newTransNode(n)
-  for i in countup(0, sonsLen(n)-1): 
+  for i in countup(0, sonsLen(n)-1):
     result[i] = transform(c, n.sons[i])
 
-proc newAsgnStmt(c: PTransf, le: PNode, ri: PTransNode): PTransNode = 
+proc newAsgnStmt(c: PTransf, le: PNode, ri: PTransNode): PTransNode =
   result = newTransNode(nkFastAsgn, PNode(ri).info, 2)
   result[0] = PTransNode(le)
   result[1] = ri
@@ -113,30 +113,30 @@ proc transformSymAux(c: PTransf, n: PNode): PNode =
   #  return liftIterSym(n)
   var b: PNode
   var tc = c.transCon
-  if sfBorrow in n.sym.flags: 
+  if sfBorrow in n.sym.flags:
     # simply exchange the symbol:
     b = n.sym.getBody
     if b.kind != nkSym: internalError(n.info, "wrong AST for borrowed symbol")
     b = newSymNode(b.sym)
     b.info = n.info
-  else: 
+  else:
     b = n
-  while tc != nil: 
+  while tc != nil:
     result = idNodeTableGet(tc.mapping, b.sym)
     if result != nil: return
     tc = tc.next
   result = b
 
-proc transformSym(c: PTransf, n: PNode): PTransNode = 
+proc transformSym(c: PTransf, n: PNode): PTransNode =
   result = PTransNode(transformSymAux(c, n))
 
 proc transformVarSection(c: PTransf, v: PNode): PTransNode =
   result = newTransNode(v)
   for i in countup(0, sonsLen(v)-1):
     var it = v.sons[i]
-    if it.kind == nkCommentStmt: 
+    if it.kind == nkCommentStmt:
       result[i] = PTransNode(it)
-    elif it.kind == nkIdentDefs: 
+    elif it.kind == nkIdentDefs:
       if it.sons[0].kind != nkSym: internalError(it.info, "transformVarSection")
       internalAssert(it.len == 3)
       var newVar = copySym(it.sons[0].sym)
@@ -153,12 +153,12 @@ proc transformVarSection(c: PTransf, v: PNode): PTransNode =
       defs[1] = it.sons[1].PTransNode
       defs[2] = transform(c, it.sons[2])
       result[i] = defs
-    else: 
-      if it.kind != nkVarTuple: 
+    else:
+      if it.kind != nkVarTuple:
         internalError(it.info, "transformVarSection: not nkVarTuple")
       var L = sonsLen(it)
       var defs = newTransNode(it.kind, it.info, L)
-      for j in countup(0, L-3): 
+      for j in countup(0, L-3):
         var newVar = copySym(it.sons[j].sym)
         incl(newVar.flags, sfFromGeneric)
         newVar.owner = getCurrOwner(c)
@@ -188,12 +188,12 @@ proc transformConstSection(c: PTransf, v: PNode): PTransNode =
       else:
         result[i] = PTransNode(it)
 
-proc hasContinue(n: PNode): bool = 
+proc hasContinue(n: PNode): bool =
   case n.kind
   of nkEmpty..nkNilLit, nkForStmt, nkParForStmt, nkWhileStmt: discard
   of nkContinueStmt: result = true
-  else: 
-    for i in countup(0, sonsLen(n) - 1): 
+  else:
+    for i in countup(0, sonsLen(n) - 1):
       if hasContinue(n.sons[i]): return true
 
 proc newLabel(c: PTransf, n: PNode): PSym =
@@ -224,10 +224,10 @@ proc transformBlock(c: PTransf, n: PNode): PTransNode =
   discard c.breakSyms.pop
   result[0] = newSymNode(labl).PTransNode
 
-proc transformLoopBody(c: PTransf, n: PNode): PTransNode =  
-  # What if it contains "continue" and "break"? "break" needs 
+proc transformLoopBody(c: PTransf, n: PNode): PTransNode =
+  # What if it contains "continue" and "break"? "break" needs
   # an explicit label too, but not the same!
-  
+
   # We fix this here by making every 'break' belong to its enclosing loop
   # and changing all breaks that belong to a 'block' by annotating it with
   # a label (if it hasn't one already).
@@ -239,7 +239,7 @@ proc transformLoopBody(c: PTransf, n: PNode): PTransNode =
     result[0] = newSymNode(labl).PTransNode
     result[1] = transform(c, n)
     discard c.contSyms.pop()
-  else: 
+  else:
     result = transform(c, n)
 
 proc transformWhile(c: PTransf; n: PNode): PTransNode =
@@ -273,27 +273,27 @@ proc transformBreak(c: PTransf, n: PNode): PTransNode =
     result = transformSons(c, n)
     result[0] = newSymNode(labl).PTransNode
 
-proc unpackTuple(c: PTransf, n: PNode, father: PTransNode) = 
+proc unpackTuple(c: PTransf, n: PNode, father: PTransNode) =
   # XXX: BUG: what if `n` is an expression with side-effects?
-  for i in countup(0, sonsLen(c.transCon.forStmt) - 3): 
-    add(father, newAsgnStmt(c, c.transCon.forStmt.sons[i], 
+  for i in countup(0, sonsLen(c.transCon.forStmt) - 3):
+    add(father, newAsgnStmt(c, c.transCon.forStmt.sons[i],
         transform(c, newTupleAccess(n, i))))
 
-proc introduceNewLocalVars(c: PTransf, n: PNode): PTransNode = 
+proc introduceNewLocalVars(c: PTransf, n: PNode): PTransNode =
   case n.kind
-  of nkSym: 
+  of nkSym:
     result = transformSym(c, n)
-  of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit: 
+  of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit:
     # nothing to be done for leaves:
     result = PTransNode(n)
   of nkVarSection, nkLetSection:
     result = transformVarSection(c, n)
   else:
     result = newTransNode(n)
-    for i in countup(0, sonsLen(n)-1): 
+    for i in countup(0, sonsLen(n)-1):
       result[i] =  introduceNewLocalVars(c, n.sons[i])
 
-proc transformYield(c: PTransf, n: PNode): PTransNode = 
+proc transformYield(c: PTransf, n: PNode): PTransNode =
   result = newTransNode(nkStmtList, n.info, 0)
   var e = n.sons[0]
   # c.transCon.forStmt.len == 3 means that there is one for loop variable
@@ -301,21 +301,21 @@ proc transformYield(c: PTransf, n: PNode): PTransNode =
   if skipTypes(e.typ, {tyGenericInst}).kind == tyTuple and
       c.transCon.forStmt.len != 3:
     e = skipConv(e)
-    if e.kind == nkPar: 
-      for i in countup(0, sonsLen(e) - 1): 
-        add(result, newAsgnStmt(c, c.transCon.forStmt.sons[i], 
+    if e.kind == nkPar:
+      for i in countup(0, sonsLen(e) - 1):
+        add(result, newAsgnStmt(c, c.transCon.forStmt.sons[i],
                                 transform(c, e.sons[i])))
-    else: 
+    else:
       unpackTuple(c, e, result)
-  else: 
+  else:
     var x = transform(c, e)
     add(result, newAsgnStmt(c, c.transCon.forStmt.sons[0], x))
-  
+
   inc(c.transCon.yieldStmts)
   if c.transCon.yieldStmts <= 1:
     # common case
     add(result, c.transCon.forLoopBody)
-  else: 
+  else:
     # we need to introduce new local variables:
     add(result, introduceNewLocalVars(c, c.transCon.forLoopBody.PNode))
 
@@ -340,25 +340,25 @@ proc transformAddrDeref(c: PTransf, n: PNode, a, b: TNodeKind): PTransNode =
     if n.sons[0].kind == a or n.sons[0].kind == b:
       # addr ( deref ( x )) --> x
       result = PTransNode(n.sons[0].sons[0])
-  
-proc transformConv(c: PTransf, n: PNode): PTransNode = 
+
+proc transformConv(c: PTransf, n: PNode): PTransNode =
   # numeric types need range checks:
   var dest = skipTypes(n.typ, abstractVarRange)
   var source = skipTypes(n.sons[1].typ, abstractVarRange)
   case dest.kind
-  of tyInt..tyInt64, tyEnum, tyChar, tyBool, tyUInt8..tyUInt32: 
+  of tyInt..tyInt64, tyEnum, tyChar, tyBool, tyUInt8..tyUInt32:
     # we don't include uint and uint64 here as these are no ordinal types ;-)
     if not isOrdinalType(source):
       # float -> int conversions. ugh.
       result = transformSons(c, n)
     elif firstOrd(n.typ) <= firstOrd(n.sons[1].typ) and
-        lastOrd(n.sons[1].typ) <= lastOrd(n.typ): 
+        lastOrd(n.sons[1].typ) <= lastOrd(n.typ):
       # BUGFIX: simply leave n as it is; we need a nkConv node,
       # but no range check:
       result = transformSons(c, n)
-    else: 
+    else:
       # generate a range check:
-      if dest.kind == tyInt64 or source.kind == tyInt64: 
+      if dest.kind == tyInt64 or source.kind == tyInt64:
         result = newTransNode(nkChckRange64, n, 3)
       else:
         result = newTransNode(nkChckRange, n, 3)
@@ -368,7 +368,7 @@ proc transformConv(c: PTransf, n: PNode): PTransNode =
       result[2] = newIntTypeNode(nkIntLit, lastOrd(dest), source).PTransNode
   of tyFloat..tyFloat128:
     # XXX int64 -> float conversion?
-    if skipTypes(n.typ, abstractVar).kind == tyRange: 
+    if skipTypes(n.typ, abstractVar).kind == tyRange:
       result = newTransNode(nkChckRangeF, n, 3)
       dest = skipTypes(n.typ, abstractVar)
       result[0] = transform(c, n.sons[1])
@@ -378,81 +378,81 @@ proc transformConv(c: PTransf, n: PNode): PTransNode =
       result = transformSons(c, n)
   of tyOpenArray, tyVarargs:
     result = transform(c, n.sons[1])
-  of tyCString: 
-    if source.kind == tyString: 
+  of tyCString:
+    if source.kind == tyString:
       result = newTransNode(nkStringToCString, n, 1)
       result[0] = transform(c, n.sons[1])
     else:
       result = transformSons(c, n)
-  of tyString: 
-    if source.kind == tyCString: 
+  of tyString:
+    if source.kind == tyCString:
       result = newTransNode(nkCStringToString, n, 1)
       result[0] = transform(c, n.sons[1])
     else:
       result = transformSons(c, n)
-  of tyRef, tyPtr: 
+  of tyRef, tyPtr:
     dest = skipTypes(dest, abstractPtrs)
     source = skipTypes(source, abstractPtrs)
-    if source.kind == tyObject: 
+    if source.kind == tyObject:
       var diff = inheritanceDiff(dest, source)
-      if diff < 0: 
+      if diff < 0:
         result = newTransNode(nkObjUpConv, n, 1)
         result[0] = transform(c, n.sons[1])
-      elif diff > 0: 
+      elif diff > 0:
         result = newTransNode(nkObjDownConv, n, 1)
         result[0] = transform(c, n.sons[1])
-      else: 
+      else:
         result = transform(c, n.sons[1])
     else:
       result = transformSons(c, n)
-  of tyObject: 
+  of tyObject:
     var diff = inheritanceDiff(dest, source)
-    if diff < 0: 
+    if diff < 0:
       result = newTransNode(nkObjUpConv, n, 1)
       result[0] = transform(c, n.sons[1])
-    elif diff > 0: 
+    elif diff > 0:
       result = newTransNode(nkObjDownConv, n, 1)
       result[0] = transform(c, n.sons[1])
-    else: 
+    else:
       result = transform(c, n.sons[1])
   of tyGenericParam, tyOrdinal:
     result = transform(c, n.sons[1])
     # happens sometimes for generated assignments, etc.
-  else: 
+  else:
     result = transformSons(c, n)
-  
-type 
-  TPutArgInto = enum 
+
+type
+  TPutArgInto = enum
     paDirectMapping, paFastAsgn, paVarAsgn
 
-proc putArgInto(arg: PNode, formal: PType): TPutArgInto = 
+proc putArgInto(arg: PNode, formal: PType): TPutArgInto =
   # This analyses how to treat the mapping "formal <-> arg" in an
   # inline context.
   if skipTypes(formal, abstractInst).kind in {tyOpenArray, tyVarargs}:
     return paDirectMapping    # XXX really correct?
                               # what if ``arg`` has side-effects?
   case arg.kind
-  of nkEmpty..nkNilLit: 
+  of nkEmpty..nkNilLit:
     result = paDirectMapping
-  of nkPar, nkCurly, nkBracket: 
+  of nkPar, nkCurly, nkBracket:
     result = paFastAsgn
-    for i in countup(0, sonsLen(arg) - 1): 
-      if putArgInto(arg.sons[i], formal) != paDirectMapping: return 
+    for i in countup(0, sonsLen(arg) - 1):
+      if putArgInto(arg.sons[i], formal) != paDirectMapping: return
     result = paDirectMapping
-  else: 
+  else:
     if skipTypes(formal, abstractInst).kind == tyVar: result = paVarAsgn
     else: result = paFastAsgn
-  
+
 proc findWrongOwners(c: PTransf, n: PNode) =
   if n.kind == nkVarSection:
     let x = n.sons[0].sons[0]
     if x.kind == nkSym and x.sym.owner != getCurrOwner(c):
-      internalError(x.info, "bah " & x.sym.name.s & " " & 
+      internalError(x.info, "bah " & x.sym.name.s & " " &
         x.sym.owner.name.s & " " & getCurrOwner(c).name.s)
   else:
     for i in 0 .. <safeLen(n): findWrongOwners(c, n.sons[i])
 
-proc transformFor(c: PTransf, n: PNode): PTransNode = 
+proc transformFor(c: PTransf, n: PNode): PTransNode =
   # generate access statements for the parameters (unless they are constant)
   # put mapping from formal parameters to actual parameters
   if n.kind != nkForStmt: internalError(n.info, "transformFor")
@@ -466,26 +466,26 @@ proc transformFor(c: PTransf, n: PNode): PTransNode =
   result[0] = newSymNode(labl).PTransNode
 
   if call.typ.kind != tyIter and
-    (call.kind notin nkCallKinds or call.sons[0].kind != nkSym or 
+    (call.kind notin nkCallKinds or call.sons[0].kind != nkSym or
       call.sons[0].sym.kind != skIterator):
     n.sons[length-1] = transformLoopBody(c, n.sons[length-1]).PNode
     result[1] = lambdalifting.liftForLoop(n).PTransNode
     discard c.breakSyms.pop
     return result
-  
+
   #echo "transforming: ", renderTree(n)
   var stmtList = newTransNode(nkStmtList, n.info, 0)
-  
+
   var loopBody = transformLoopBody(c, n.sons[length-1])
 
   result[1] = stmtList
   discard c.breakSyms.pop
 
   var v = newNodeI(nkVarSection, n.info)
-  for i in countup(0, length - 3): 
+  for i in countup(0, length - 3):
     addVar(v, copyTree(n.sons[i])) # declare new vars
   add(stmtList, v.PTransNode)
-  
+
   # Bugfix: inlined locals belong to the invoking routine, not to the invoked
   # iterator!
   let iter = call.sons[0].sym
@@ -496,9 +496,9 @@ proc transformFor(c: PTransf, n: PNode): PTransNode =
   if iter.kind != skIterator: return result
   # generate access statements for the parameters (unless they are constant)
   pushTransCon(c, newC)
-  for i in countup(1, sonsLen(call) - 1): 
+  for i in countup(1, sonsLen(call) - 1):
     var arg = transform(c, call.sons[i]).PNode
-    var formal = skipTypes(iter.typ, abstractInst).n.sons[i].sym 
+    var formal = skipTypes(iter.typ, abstractInst).n.sons[i].sym
     if arg.typ.kind == tyIter: continue
     case putArgInto(arg, formal.typ)
     of paDirectMapping:
@@ -527,20 +527,20 @@ proc transformFor(c: PTransf, n: PNode): PTransNode =
   popInfoContext()
   popTransCon(c)
   # echo "transformed: ", stmtList.PNode.renderTree
-  
-proc getMagicOp(call: PNode): TMagic = 
+
+proc getMagicOp(call: PNode): TMagic =
   if call.sons[0].kind == nkSym and
-      call.sons[0].sym.kind in {skProc, skMethod, skConverter}: 
+      call.sons[0].sym.kind in {skProc, skMethod, skConverter}:
     result = call.sons[0].sym.magic
   else:
     result = mNone
 
-proc transformCase(c: PTransf, n: PNode): PTransNode = 
+proc transformCase(c: PTransf, n: PNode): PTransNode =
   # removes `elif` branches of a case stmt
   # adds ``else: nil`` if needed for the code generator
   result = newTransNode(nkCaseStmt, n, 0)
   var ifs = PTransNode(nil)
-  for i in 0 .. sonsLen(n)-1: 
+  for i in 0 .. sonsLen(n)-1:
     var it = n.sons[i]
     var e = transform(c, it)
     case it.kind
@@ -564,8 +564,8 @@ proc transformCase(c: PTransf, n: PNode): PTransNode =
     var elseBranch = newTransNode(nkElse, n.info, 1)
     elseBranch[0] = newTransNode(nkNilLit, n.info, 0)
     add(result, elseBranch)
-  
-proc transformArrayAccess(c: PTransf, n: PNode): PTransNode = 
+
+proc transformArrayAccess(c: PTransf, n: PNode): PTransNode =
   # XXX this is really bad; transf should use a proper AST visitor
   if n.sons[0].kind == nkSym and n.sons[0].sym.kind == skType:
     result = n.PTransNode
@@ -573,45 +573,45 @@ proc transformArrayAccess(c: PTransf, n: PNode): PTransNode =
     result = newTransNode(n)
     for i in 0 .. < n.len:
       result[i] = transform(c, skipConv(n.sons[i]))
-  
-proc getMergeOp(n: PNode): PSym = 
+
+proc getMergeOp(n: PNode): PSym =
   case n.kind
-  of nkCall, nkHiddenCallConv, nkCommand, nkInfix, nkPrefix, nkPostfix, 
-     nkCallStrLit: 
+  of nkCall, nkHiddenCallConv, nkCommand, nkInfix, nkPrefix, nkPostfix,
+     nkCallStrLit:
     if (n.sons[0].kind == nkSym) and (n.sons[0].sym.kind == skProc) and
-        (sfMerge in n.sons[0].sym.flags): 
+        (sfMerge in n.sons[0].sym.flags):
       result = n.sons[0].sym
   else: discard
 
-proc flattenTreeAux(d, a: PNode, op: PSym) = 
+proc flattenTreeAux(d, a: PNode, op: PSym) =
   let op2 = getMergeOp(a)
   if op2 != nil and
-      (op2.id == op.id or op.magic != mNone and op2.magic == op.magic): 
+      (op2.id == op.id or op.magic != mNone and op2.magic == op.magic):
     for i in countup(1, sonsLen(a)-1): flattenTreeAux(d, a.sons[i], op)
-  else: 
+  else:
     addSon(d, copyTree(a))
-  
-proc flattenTree(root: PNode): PNode = 
+
+proc flattenTree(root: PNode): PNode =
   let op = getMergeOp(root)
-  if op != nil: 
+  if op != nil:
     result = copyNode(root)
     addSon(result, copyTree(root.sons[0]))
     flattenTreeAux(result, root, op)
-  else: 
+  else:
     result = root
 
-proc transformCall(c: PTransf, n: PNode): PTransNode = 
+proc transformCall(c: PTransf, n: PNode): PTransNode =
   var n = flattenTree(n)
   let op = getMergeOp(n)
   let magic = getMagic(n)
-  if op != nil and op.magic != mNone and n.len >= 3: 
+  if op != nil and op.magic != mNone and n.len >= 3:
     result = newTransNode(nkCall, n, 0)
     add(result, transform(c, n.sons[0]))
     var j = 1
-    while j < sonsLen(n): 
+    while j < sonsLen(n):
       var a = transform(c, n.sons[j]).PNode
       inc(j)
-      if isConstExpr(a): 
+      if isConstExpr(a):
         while (j < sonsLen(n)):
           let b = transform(c, n.sons[j]).PNode
           if not isConstExpr(b): break
@@ -640,7 +640,7 @@ proc transformCall(c: PTransf, n: PNode): PTransNode =
 proc dontInlineConstant(orig, cnst: PNode): bool {.inline.} =
   # symbols that expand to a complex constant (array, etc.) should not be
   # inlined, unless it's the empty array:
-  result = orig.kind == nkSym and cnst.kind in {nkCurly, nkPar, nkBracket} and 
+  result = orig.kind == nkSym and cnst.kind in {nkCurly, nkPar, nkBracket} and
       cnst.len != 0
 
 proc commonOptimizations*(c: PSym, n: PNode): PNode =
@@ -673,11 +673,11 @@ proc commonOptimizations*(c: PSym, n: PNode): PNode =
     else:
       result = n
 
-proc transform(c: PTransf, n: PNode): PTransNode = 
+proc transform(c: PTransf, n: PNode): PTransNode =
   case n.kind
-  of nkSym: 
+  of nkSym:
     result = transformSym(c, n)
-  of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit: 
+  of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit:
     # nothing to be done for leaves:
     result = PTransNode(n)
   of nkBracketExpr: result = transformArrayAccess(c, n)
@@ -702,7 +702,7 @@ proc transform(c: PTransf, n: PNode): PTransNode =
         n.sons[bodyPos] = PNode(transform(c, s.getBody))
         if n.kind == nkMethodDef: methodDef(s, false)
     result = PTransNode(n)
-  of nkForStmt: 
+  of nkForStmt:
     result = transformFor(c, n)
   of nkParForStmt:
     result = transformSons(c, n)
@@ -713,14 +713,14 @@ proc transform(c: PTransf, n: PNode): PTransNode =
     add(result, PTransNode(newSymNode(labl)))
   of nkBreakStmt: result = transformBreak(c, n)
   of nkWhileStmt: result = transformWhile(c, n)
-  of nkCall, nkHiddenCallConv, nkCommand, nkInfix, nkPrefix, nkPostfix, 
-     nkCallStrLit: 
+  of nkCall, nkHiddenCallConv, nkCommand, nkInfix, nkPrefix, nkPostfix,
+     nkCallStrLit:
     result = transformCall(c, n)
-  of nkAddr, nkHiddenAddr: 
+  of nkAddr, nkHiddenAddr:
     result = transformAddrDeref(c, n, nkDerefExpr, nkHiddenDeref)
-  of nkDerefExpr, nkHiddenDeref: 
+  of nkDerefExpr, nkHiddenDeref:
     result = transformAddrDeref(c, n, nkAddr, nkHiddenAddr)
-  of nkHiddenStdConv, nkHiddenSubConv, nkConv: 
+  of nkHiddenStdConv, nkHiddenSubConv, nkConv:
     result = transformConv(c, n)
   of nkDiscardStmt:
     result = PTransNode(n)
@@ -730,7 +730,7 @@ proc transform(c: PTransf, n: PNode): PTransNode =
         # ensure that e.g. discard "some comment" gets optimized away
         # completely:
         result = PTransNode(newNode(nkCommentStmt))
-  of nkCommentStmt, nkTemplateDef: 
+  of nkCommentStmt, nkTemplateDef:
     return n.PTransNode
   of nkConstSection:
     # do not replace ``const c = 3`` with ``const 3 = 3``
@@ -744,10 +744,10 @@ proc transform(c: PTransf, n: PNode): PTransNode =
       result = transformVarSection(c, n)
     else:
       result = transformSons(c, n)
-  of nkYieldStmt: 
+  of nkYieldStmt:
     if c.inlining > 0:
       result = transformYield(c, n)
-    else: 
+    else:
       result = transformSons(c, n)
   of nkBlockStmt, nkBlockExpr:
     result = transformBlock(c, n)
@@ -764,7 +764,7 @@ proc transform(c: PTransf, n: PNode): PTransNode =
   if cnst != nil and not dontInlineConstant(n, cnst):
     result = PTransNode(cnst) # do not miss an optimization
 
-proc processTransf(c: PTransf, n: PNode, owner: PSym): PNode = 
+proc processTransf(c: PTransf, n: PNode, owner: PSym): PNode =
   # Note: For interactive mode we cannot call 'passes.skipCodegen' and skip
   # this step! We have to rely that the semantic pass transforms too errornous
   # nodes into an empty node.
@@ -774,7 +774,7 @@ proc processTransf(c: PTransf, n: PNode, owner: PSym): PNode =
   popTransCon(c)
   incl(result.flags, nfTransf)
 
-proc openTransf(module: PSym, filename: string): PTransf = 
+proc openTransf(module: PSym, filename: string): PTransf =
   new(result)
   result.contSyms = @[]
   result.breakSyms = @[]