mirror of
https://github.com/nim-lang/Nim.git
synced 2026-07-19 23:41:29 +00:00
checkpoint
This commit is contained in:
@@ -231,7 +231,7 @@ type
|
||||
TNodeKinds* = set[TNodeKind]
|
||||
|
||||
type
|
||||
TSymFlag* = enum # 51 flags!
|
||||
TSymFlag* = enum # 52 flags!
|
||||
sfUsed, # read access of sym (for warnings) or simply used
|
||||
sfExported, # symbol is exported from module
|
||||
sfFromGeneric, # symbol is instantiation of a generic; this is needed
|
||||
@@ -316,6 +316,7 @@ type
|
||||
sfByCopy # param is marked as pass bycopy
|
||||
sfMember # proc is a C++ member of a type
|
||||
sfCodegenDecl # type, proc, global or proc param is marked as codegenDecl
|
||||
sfToplevelDecl
|
||||
|
||||
TSymFlags* = set[TSymFlag]
|
||||
|
||||
|
||||
@@ -222,6 +222,7 @@ type
|
||||
strictDefs,
|
||||
strictCaseObjects,
|
||||
inferGenericTypes
|
||||
noforwardDecl
|
||||
|
||||
LegacyFeature* = enum
|
||||
allowSemcheckedAstModification,
|
||||
|
||||
@@ -81,9 +81,9 @@ proc prePass(c: PContext; n: PNode) =
|
||||
of nkStrLit, nkRStrLit, nkTripleStrLit:
|
||||
try:
|
||||
let feature = parseEnum[Feature](name.strVal)
|
||||
if feature == codeReordering:
|
||||
c.features.incl feature
|
||||
c.module.flags.incl sfReorder
|
||||
# if feature == codeReordering:
|
||||
c.features.incl feature
|
||||
c.module.flags.incl sfReorder
|
||||
except ValueError:
|
||||
discard
|
||||
else:
|
||||
|
||||
@@ -34,7 +34,7 @@ proc searchForProcAux(c: PContext, scope: PScope, fn: PSym): PSym =
|
||||
var it: TIdentIter
|
||||
result = initIdentIter(it, scope.symbols, fn.name)
|
||||
while result != nil:
|
||||
if result.kind == fn.kind: #and sameType(result.typ, fn.typ, flags):
|
||||
if result.kind == fn.kind and result.typ != nil: #and sameType(result.typ, fn.typ, flags):
|
||||
case equalParams(result.typ.n, fn.typ.n)
|
||||
of paramsEqual:
|
||||
if (sfExported notin result.flags) and (sfExported in fn.flags):
|
||||
|
||||
@@ -762,6 +762,58 @@ proc isEmptyTree(n: PNode): bool =
|
||||
of nkEmpty, nkCommentStmt: result = true
|
||||
else: result = false
|
||||
|
||||
proc decl(c: PContext, n: PNode, kind: TSymKind): PNode =
|
||||
if n[0].kind == nkIdent:
|
||||
var s = newSym(kind, n[0].ident, c.idgen, getCurrOwner(c), n.info)
|
||||
s.flags.incl sfToplevelDecl
|
||||
# pragmaCallable(c, s, n, allRoutinePragmas)
|
||||
|
||||
result = n
|
||||
if n[^1].kind != nkEmpty:
|
||||
if s.kind in OverloadableSyms:
|
||||
addInterfaceOverloadableSymAt(c, c.currentScope, s)
|
||||
else:
|
||||
addInterfaceDeclAt(c, c.currentScope, s)
|
||||
|
||||
result[0] = newSymNode(s)
|
||||
else:
|
||||
result = n
|
||||
|
||||
import reorder
|
||||
|
||||
proc semSignature(c: PContext, n: PNode): PNode =
|
||||
case n.kind
|
||||
of nkProcDef:
|
||||
result = decl(c, n, skProc)
|
||||
of nkMethodDef:
|
||||
result = decl(c, n, skMethod)
|
||||
of nkConverterDef:
|
||||
result = decl(c, n, skConverter)
|
||||
of nkMacroDef:
|
||||
result = decl(c, n, skMacro)
|
||||
of nkTemplateDef:
|
||||
result = decl(c, n, skTemplate)
|
||||
of nkIteratorDef:
|
||||
result = decl(c, n, skIterator)
|
||||
of nkIncludeStmt:
|
||||
result = n
|
||||
for i in 0..<n.len:
|
||||
var f = checkModuleName(c.config, n[i])
|
||||
if f != InvalidFileIdx:
|
||||
if containsOrIncl(c.includedFiles, f.int):
|
||||
localError(c.config, n[i].info, "recursive dependency: '$1'" %
|
||||
toMsgFilename(c.config, f))
|
||||
else:
|
||||
let nn = includeModule(c.graph, c.module, f)
|
||||
result = semSignature(c, nn)
|
||||
excl(c.includedFiles, f.int)
|
||||
of nkStmtList:
|
||||
result = copyNode(n)
|
||||
for i in 0..<n.len:
|
||||
result.add semSignature(c, n[i])
|
||||
else:
|
||||
result = n
|
||||
|
||||
proc semStmtAndGenerateGenerics(c: PContext, n: PNode): PNode =
|
||||
if c.topStmts == 0 and not isImportSystemStmt(c.graph, n):
|
||||
if sfSystemModule notin c.module.flags and not isEmptyTree(n):
|
||||
@@ -775,6 +827,9 @@ proc semStmtAndGenerateGenerics(c: PContext, n: PNode): PNode =
|
||||
result = semAllTypeSections(c, n)
|
||||
else:
|
||||
result = n
|
||||
# if noforwardDecl in c.features:
|
||||
# debug result
|
||||
result = semSignature(c, result)
|
||||
result = semStmt(c, result, {})
|
||||
when false:
|
||||
# Code generators are lazy now and can deal with undeclared procs, so these
|
||||
|
||||
@@ -1726,6 +1726,7 @@ proc semProcAnnotation(c: PContext, prc: PNode;
|
||||
validPragmas: TSpecialWords): PNode =
|
||||
# Mirrored with semVarMacroPragma
|
||||
result = nil
|
||||
doAssert prc != nil
|
||||
var n = prc[pragmasPos]
|
||||
if n == nil or n.kind == nkEmpty: return
|
||||
for i in 0..<n.len:
|
||||
@@ -2175,6 +2176,12 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||
var (proto, comesFromShadowScope) =
|
||||
if isAnon: (nil, false)
|
||||
else: searchForProc(c, declarationScope, s)
|
||||
|
||||
# if sfToplevelDecl in s.flags and proto != nil:
|
||||
# # symTabRemove(declarationScope.symbols, proto)
|
||||
# s.flags.incl proto.flags # copy flags of forward decls
|
||||
# proto = nil
|
||||
|
||||
if proto == nil and sfForward in s.flags and n[bodyPos].kind != nkEmpty:
|
||||
## In cases such as a macro generating a proc with a gensymmed name we
|
||||
## know `searchForProc` will not find it and sfForward will be set. In
|
||||
@@ -2204,11 +2211,6 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||
# pragma analysis further down.
|
||||
s.typ.callConv = lastOptionEntry(c).defaultCC
|
||||
|
||||
if not hasProto and sfGenSym notin s.flags: #and not isAnon:
|
||||
if s.kind in OverloadableSyms:
|
||||
addInterfaceOverloadableSymAt(c, declarationScope, s)
|
||||
else:
|
||||
addInterfaceDeclAt(c, declarationScope, s)
|
||||
|
||||
pragmaCallable(c, s, n, validPragmas)
|
||||
if not hasProto:
|
||||
@@ -2218,6 +2220,18 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||
setEffectsForProcType(c.graph, s.typ, n[pragmasPos], s)
|
||||
s.typ.flags.incl tfEffectSystemWorkaround
|
||||
|
||||
let isForwards = n[bodyPos].kind == nkEmpty and {sfImportc, sfBorrow, sfError} * s.flags == {} and s.magic == mNone
|
||||
# delay
|
||||
if ((sfToplevelDecl notin s.flags or
|
||||
{sfImportc, sfBorrow, sfError} * s.flags != {} or
|
||||
s.magic != mNone
|
||||
) and
|
||||
not hasProto and sfGenSym notin s.flags): #and not isAnon:
|
||||
if s.kind in OverloadableSyms:
|
||||
addInterfaceOverloadableSymAt(c, declarationScope, s)
|
||||
else:
|
||||
addInterfaceDeclAt(c, declarationScope, s)
|
||||
|
||||
# To ease macro generation that produce forwarded .async procs we now
|
||||
# allow a bit redundancy in the pragma declarations. The rule is
|
||||
# a prototype's pragma list must be a superset of the current pragma
|
||||
@@ -2240,7 +2254,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||
onDef(n[namePos].info, s)
|
||||
|
||||
if hasProto:
|
||||
if sfForward notin proto.flags and proto.magic == mNone:
|
||||
if sfForward notin proto.flags and sfToplevelDecl notin proto.flags and proto.magic == mNone:
|
||||
wrongRedefinition(c, n.info, proto.name.s, proto.info)
|
||||
if not comesFromShadowScope:
|
||||
excl(proto.flags, sfForward)
|
||||
@@ -2389,7 +2403,9 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||
proc determineType(c: PContext, s: PSym) =
|
||||
if s.typ != nil: return
|
||||
#if s.magic != mNone: return
|
||||
#if s.ast.isNil: return
|
||||
# if s.ast.isNil: return
|
||||
if s.ast == nil:
|
||||
debug s
|
||||
discard semProcAux(c, s.ast, s.kind, {})
|
||||
|
||||
proc semIterator(c: PContext, n: PNode): PNode =
|
||||
|
||||
@@ -2473,6 +2473,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode, m: var TCandidate, marker: var Int
|
||||
|
||||
m.state = csMatch # until proven otherwise
|
||||
m.firstMismatch = MismatchInfo()
|
||||
doAssert m.callee != nil
|
||||
m.call = newNodeIT(n.kind, n.info, m.callee.base)
|
||||
m.call.add n[0]
|
||||
|
||||
|
||||
11
tests/forward/t1.nim
Normal file
11
tests/forward/t1.nim
Normal file
@@ -0,0 +1,11 @@
|
||||
{.experimental: "noforwardDecl".}
|
||||
|
||||
proc bar(x: int) =
|
||||
var s = 1
|
||||
inc s, x
|
||||
foo(s)
|
||||
|
||||
proc foo(x: int) =
|
||||
echo x
|
||||
|
||||
bar(999)
|
||||
14
tests/forward/t2.nim
Normal file
14
tests/forward/t2.nim
Normal file
@@ -0,0 +1,14 @@
|
||||
{.experimental: "noforwardDecl".}
|
||||
|
||||
proc foo(x: int)
|
||||
|
||||
proc bar(x: int) =
|
||||
var s = 1
|
||||
inc s, x
|
||||
foo(s)
|
||||
|
||||
|
||||
proc foo(x: int) =
|
||||
echo x
|
||||
|
||||
bar(999)
|
||||
15
tests/forward/t3.nim
Normal file
15
tests/forward/t3.nim
Normal file
@@ -0,0 +1,15 @@
|
||||
{.experimental: "noforwardDecl".}
|
||||
|
||||
|
||||
proc bar(x: int) =
|
||||
var s = 1
|
||||
inc s, x
|
||||
foo(s)
|
||||
|
||||
proc foo(x: int)
|
||||
|
||||
|
||||
proc foo(x: int) =
|
||||
echo x
|
||||
|
||||
bar(999)
|
||||
5
tests/options/test.h
Normal file
5
tests/options/test.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
#include "nimbase.h"
|
||||
struct Foo {
|
||||
int a;
|
||||
};
|
||||
Reference in New Issue
Block a user