implemented {.noforward:on.} for type sections; useful for c2nim generated wrappers; to be documented
This commit is contained in:
parent
a2b8b8b0dd
commit
0a624bec1e
3 changed files with 75 additions and 12 deletions
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -744,10 +744,59 @@ 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.
|
||||||
|
if sfNoForward notin c.module.flags or nfSem notin n.flags:
|
||||||
typeSectionLeftSidePass(c, n)
|
typeSectionLeftSidePass(c, n)
|
||||||
typeSectionRightSidePass(c, n)
|
typeSectionRightSidePass(c, n)
|
||||||
typeSectionFinalPass(c, n)
|
typeSectionFinalPass(c, n)
|
||||||
|
|
@ -1033,7 +1082,8 @@ 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:
|
||||||
|
# disable for now
|
||||||
if sfNoForward in c.module.flags and
|
if sfNoForward in c.module.flags and
|
||||||
sfSystemModule notin c.module.flags:
|
sfSystemModule notin c.module.flags:
|
||||||
addInterfaceOverloadableSymAt(c, c.currentScope, s)
|
addInterfaceOverloadableSymAt(c, c.currentScope, s)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue