implemented {.noforward:on.} for type sections; useful for c2nim generated wrappers; to be documented

This commit is contained in:
Araq 2015-07-08 11:12:39 +02:00
commit 0a624bec1e
3 changed files with 75 additions and 12 deletions

View file

@ -190,8 +190,17 @@ proc processModule(module: PSym, stream: PLLStream, rd: PRodReader) =
while true: while true:
var n = parseTopLevelStmt(p) var n = parseTopLevelStmt(p)
if n.kind == nkEmpty: break if n.kind == nkEmpty: break
if not processTopLevelStmt(n, a): break if sfNoForward in module.flags:
# read everything, no streaming possible
var sl = newNodeI(nkStmtList, n.info)
sl.add n
while true:
var n = parseTopLevelStmt(p)
if n.kind == nkEmpty: break
sl.add n
discard processTopLevelStmt(sl, a)
break
elif not processTopLevelStmt(n, a): break
closeParsers(p) closeParsers(p)
if s.kind != llsStdIn: break if s.kind != llsStdIn: break
closePasses(a) closePasses(a)

View file

@ -421,7 +421,11 @@ proc myOpenCached(module: PSym, rd: PRodReader): PPassContext =
for m in items(rd.methods): methodDef(m, true) for m in items(rd.methods): methodDef(m, true)
proc semStmtAndGenerateGenerics(c: PContext, n: PNode): PNode = proc semStmtAndGenerateGenerics(c: PContext, n: PNode): PNode =
result = semStmt(c, n) if sfNoForward in c.module.flags:
result = semAllTypeSections(c, n)
else:
result = n
result = semStmt(c, result)
# BUGFIX: process newly generated generics here, not at the end! # BUGFIX: process newly generated generics here, not at the end!
if c.lastGenericIdx < c.generics.len: if c.lastGenericIdx < c.generics.len:
var a = newNodeI(nkStmtList, n.info) var a = newNodeI(nkStmtList, n.info)

View file

@ -744,13 +744,62 @@ proc typeSectionFinalPass(c: PContext, n: PNode) =
if s.typ.kind in {tyObject, tyTuple} and not s.typ.n.isNil: if s.typ.kind in {tyObject, tyTuple} and not s.typ.n.isNil:
checkForMetaFields(s.typ.n) checkForMetaFields(s.typ.n)
proc semAllTypeSections(c: PContext; n: PNode): PNode =
proc gatherStmts(c: PContext; n: PNode; result: PNode) {.nimcall.} =
case n.kind
of nkIncludeStmt:
for i in 0..<n.len:
var f = checkModuleName(n.sons[i])
if f != InvalidFileIDX:
if containsOrIncl(c.includedFiles, f):
localError(n.info, errRecursiveDependencyX, f.toFilename)
else:
let code = gIncludeFile(c.module, f)
gatherStmts c, code, result
excl(c.includedFiles, f)
of nkStmtList:
for i in 0 ..< n.len:
gatherStmts(c, n.sons[i], result)
of nkTypeSection:
incl n.flags, nfSem
typeSectionLeftSidePass(c, n)
result.add n
else:
result.add n
result = newNodeI(nkStmtList, n.info)
gatherStmts(c, n, result)
template rec(name) =
for i in 0 ..< result.len:
if result[i].kind == nkTypeSection:
name(c, result[i])
rec typeSectionRightSidePass
rec typeSectionFinalPass
when false:
# too beautiful to delete:
template rec(name; setbit=false) =
proc `name rec`(c: PContext; n: PNode) {.nimcall.} =
if n.kind == nkTypeSection:
when setbit: incl n.flags, nfSem
name(c, n)
elif n.kind == nkStmtList:
for i in 0 ..< n.len:
`name rec`(c, n.sons[i])
`name rec`(c, n)
rec typeSectionLeftSidePass, true
rec typeSectionRightSidePass
rec typeSectionFinalPass
proc semTypeSection(c: PContext, n: PNode): PNode = proc semTypeSection(c: PContext, n: PNode): PNode =
## Processes a type section. This must be done in separate passes, in order ## Processes a type section. This must be done in separate passes, in order
## to allow the type definitions in the section to reference each other ## to allow the type definitions in the section to reference each other
## without regard for the order of their definitions. ## without regard for the order of their definitions.
typeSectionLeftSidePass(c, n) if sfNoForward notin c.module.flags or nfSem notin n.flags:
typeSectionRightSidePass(c, n) typeSectionLeftSidePass(c, n)
typeSectionFinalPass(c, n) typeSectionRightSidePass(c, n)
typeSectionFinalPass(c, n)
result = n result = n
proc semParamList(c: PContext, n, genericParams: PNode, s: PSym) = proc semParamList(c: PContext, n, genericParams: PNode, s: PSym) =
@ -1033,12 +1082,13 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
n.sons[namePos] = newSymNode(s) n.sons[namePos] = newSymNode(s)
s.ast = n s.ast = n
#s.scope = c.currentScope #s.scope = c.currentScope
when false:
if sfNoForward in c.module.flags and # disable for now
sfSystemModule notin c.module.flags: if sfNoForward in c.module.flags and
addInterfaceOverloadableSymAt(c, c.currentScope, s) sfSystemModule notin c.module.flags:
s.flags.incl sfForward addInterfaceOverloadableSymAt(c, c.currentScope, s)
return s.flags.incl sfForward
return
else: else:
s = n[namePos].sym s = n[namePos].sym
s.owner = getCurrOwner() s.owner = getCurrOwner()