Merge branch 'devel' into faster-nimsuggest
This commit is contained in:
commit
ba29ca0c63
52 changed files with 1048 additions and 281 deletions
|
|
@ -1541,8 +1541,7 @@ proc skipGenericOwner*(s: PSym): PSym =
|
|||
## Generic instantiations are owned by their originating generic
|
||||
## symbol. This proc skips such owners and goes straight to the owner
|
||||
## of the generic itself (the module or the enclosing proc).
|
||||
result = if s.kind in skProcKinds and {sfGenSym, sfFromGeneric} * s.flags ==
|
||||
{sfFromGeneric}:
|
||||
result = if s.kind in skProcKinds and sfFromGeneric in s.flags:
|
||||
s.owner.owner
|
||||
else:
|
||||
s.owner
|
||||
|
|
|
|||
|
|
@ -388,6 +388,7 @@ proc debugTree(n: PNode, indent: int, maxRecDepth: int;
|
|||
[istr, makeYamlString($n.kind)]
|
||||
addf(result, ",$N$1\"info\": $2", [istr, lineInfoToStr(n.info)])
|
||||
if maxRecDepth != 0:
|
||||
addf(result, ",$N$1\"flags\": $2", [istr, rope($n.flags)])
|
||||
case n.kind
|
||||
of nkCharLit..nkUInt64Lit:
|
||||
addf(result, ",$N$1\"intVal\": $2", [istr, rope(n.intVal)])
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ proc genOptAsgnTuple(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
|||
optAsgnLoc(src, t, field), newflags)
|
||||
|
||||
proc genOptAsgnObject(p: BProc, dest, src: TLoc, flags: TAssignmentFlags,
|
||||
t: PNode) =
|
||||
t: PNode, typ: PType) =
|
||||
if t == nil: return
|
||||
let newflags =
|
||||
if src.s == OnStatic:
|
||||
|
|
@ -232,10 +232,11 @@ proc genOptAsgnObject(p: BProc, dest, src: TLoc, flags: TAssignmentFlags,
|
|||
case t.kind
|
||||
of nkSym:
|
||||
let field = t.sym
|
||||
if field.loc.r == nil: fillObjectFields(p.module, typ)
|
||||
genAssignment(p, optAsgnLoc(dest, field.typ, field.loc.r),
|
||||
optAsgnLoc(src, field.typ, field.loc.r), newflags)
|
||||
of nkRecList:
|
||||
for child in items(t): genOptAsgnObject(p, dest, src, newflags, child)
|
||||
for child in items(t): genOptAsgnObject(p, dest, src, newflags, child, typ)
|
||||
else: discard
|
||||
|
||||
proc genGenericAsgn(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
||||
|
|
@ -315,9 +316,9 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
|||
genGenericAsgn(p, dest, src, flags)
|
||||
elif needsComplexAssignment(ty):
|
||||
if ty.sons[0].isNil and asgnComplexity(ty.n) <= 4:
|
||||
discard getTypeDesc(p.module, dest.t)
|
||||
discard getTypeDesc(p.module, ty)
|
||||
internalAssert ty.n != nil
|
||||
genOptAsgnObject(p, dest, src, flags, ty.n)
|
||||
genOptAsgnObject(p, dest, src, flags, ty.n, ty)
|
||||
else:
|
||||
genGenericAsgn(p, dest, src, flags)
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -1103,8 +1103,8 @@ proc asgnFieldDiscriminant(p: BProc, e: PNode) =
|
|||
genAssignment(p, a, tmp, {})
|
||||
|
||||
proc genAsgn(p: BProc, e: PNode, fastAsgn: bool) =
|
||||
genLineDir(p, e)
|
||||
if e.sons[0].kind == nkSym and sfGoto in e.sons[0].sym.flags:
|
||||
genLineDir(p, e)
|
||||
genGotoVar(p, e.sons[1])
|
||||
elif not fieldDiscriminantCheckNeeded(p, e):
|
||||
var a: TLoc
|
||||
|
|
@ -1114,8 +1114,11 @@ proc genAsgn(p: BProc, e: PNode, fastAsgn: bool) =
|
|||
initLocExpr(p, e.sons[0], a)
|
||||
if fastAsgn: incl(a.flags, lfNoDeepCopy)
|
||||
assert(a.t != nil)
|
||||
loadInto(p, e.sons[0], e.sons[1], a)
|
||||
let ri = e.sons[1]
|
||||
genLineDir(p, ri)
|
||||
loadInto(p, e.sons[0], ri, a)
|
||||
else:
|
||||
genLineDir(p, e)
|
||||
asgnFieldDiscriminant(p, e)
|
||||
|
||||
proc genStmts(p: BProc, t: PNode) =
|
||||
|
|
|
|||
|
|
@ -57,8 +57,8 @@ proc generateThreadLocalStorage(m: BModule) =
|
|||
|
||||
proc generateThreadVarsSize(m: BModule) =
|
||||
if nimtv != nil:
|
||||
let externc = if gCmd != cmdCompileToCpp and
|
||||
sfCompileToCpp in m.module.flags: "extern \"C\""
|
||||
let externc = if gCmd == cmdCompileToCpp or
|
||||
sfCompileToCpp in m.module.flags: "extern \"C\" "
|
||||
else: ""
|
||||
addf(m.s[cfsProcs],
|
||||
"$#NI NimThreadVarsSize(){return (NI)sizeof(NimThreadVars);}$n",
|
||||
|
|
|
|||
|
|
@ -715,10 +715,13 @@ proc genProcAux(m: BModule, prc: PSym) =
|
|||
add(generatedProc, ~"}$N")
|
||||
add(m.s[cfsProcs], generatedProc)
|
||||
|
||||
proc crossesCppBoundary(m: BModule; sym: PSym): bool {.inline.} =
|
||||
result = sfCompileToCpp in m.module.flags and
|
||||
proc requiresExternC(m: BModule; sym: PSym): bool {.inline.} =
|
||||
result = (sfCompileToCpp in m.module.flags and
|
||||
sfCompileToCpp notin sym.getModule().flags and
|
||||
gCmd != cmdCompileToCpp
|
||||
gCmd != cmdCompileToCpp) or (
|
||||
sym.flags * {sfImportc, sfInfixCall, sfCompilerProc} == {sfImportc} and
|
||||
sym.magic == mNone and
|
||||
gCmd == cmdCompileToCpp)
|
||||
|
||||
proc genProcPrototype(m: BModule, sym: PSym) =
|
||||
useHeader(m, sym)
|
||||
|
|
@ -732,7 +735,7 @@ proc genProcPrototype(m: BModule, sym: PSym) =
|
|||
var header = genProcHeader(m, sym)
|
||||
if sfNoReturn in sym.flags and hasDeclspec in extccomp.CC[cCompiler].props:
|
||||
header = "__declspec(noreturn) " & header
|
||||
if sym.typ.callConv != ccInline and crossesCppBoundary(m, sym):
|
||||
if sym.typ.callConv != ccInline and requiresExternC(m, sym):
|
||||
header = "extern \"C\" " & header
|
||||
if sfPure in sym.flags and hasAttribute in CC[cCompiler].props:
|
||||
header.add(" __attribute__((naked))")
|
||||
|
|
|
|||
|
|
@ -566,16 +566,18 @@ proc needsExeExt(): bool {.inline.} =
|
|||
result = (optGenScript in gGlobalOptions and targetOS == osWindows) or
|
||||
(platform.hostOS == osWindows)
|
||||
|
||||
proc getCompilerExe(compiler: TSystemCC): string =
|
||||
result = if gCmd == cmdCompileToCpp: CC[compiler].cppCompiler
|
||||
else: CC[compiler].compilerExe
|
||||
proc getCompilerExe(compiler: TSystemCC; cfile: string): string =
|
||||
result = if gCmd == cmdCompileToCpp and not cfile.endsWith(".c"):
|
||||
CC[compiler].cppCompiler
|
||||
else:
|
||||
CC[compiler].compilerExe
|
||||
if result.len == 0:
|
||||
rawMessage(errCompilerDoesntSupportTarget, CC[compiler].name)
|
||||
|
||||
proc getLinkerExe(compiler: TSystemCC): string =
|
||||
result = if CC[compiler].linkerExe.len > 0: CC[compiler].linkerExe
|
||||
elif gMixedMode and gCmd != cmdCompileToCpp: CC[compiler].cppCompiler
|
||||
else: compiler.getCompilerExe
|
||||
else: compiler.getCompilerExe("")
|
||||
|
||||
proc getCompileCFileCmd*(cfile: Cfile): string =
|
||||
var c = cCompiler
|
||||
|
|
@ -596,7 +598,7 @@ proc getCompileCFileCmd*(cfile: Cfile): string =
|
|||
|
||||
var options = cFileSpecificOptions(cfile.cname)
|
||||
var exe = getConfigVar(c, ".exe")
|
||||
if exe.len == 0: exe = c.getCompilerExe
|
||||
if exe.len == 0: exe = c.getCompilerExe(cfile.cname)
|
||||
|
||||
if needsExeExt(): exe = addFileExt(exe, "exe")
|
||||
if optGenDynLib in gGlobalOptions and
|
||||
|
|
@ -614,7 +616,7 @@ proc getCompileCFileCmd*(cfile: Cfile): string =
|
|||
compilePattern = joinPath(ccompilerpath, exe)
|
||||
else:
|
||||
includeCmd = ""
|
||||
compilePattern = c.getCompilerExe
|
||||
compilePattern = c.getCompilerExe(cfile.cname)
|
||||
|
||||
var cf = if noAbsolutePaths(): extractFilename(cfile.cname)
|
||||
else: cfile.cname
|
||||
|
|
|
|||
|
|
@ -178,6 +178,11 @@ proc newSymG*(kind: TSymKind, n: PNode, c: PContext): PSym =
|
|||
if result.kind != kind:
|
||||
localError(n.info, "cannot use symbol of kind '" &
|
||||
$result.kind & "' as a '" & $kind & "'")
|
||||
if sfGenSym in result.flags and result.kind notin {skTemplate, skMacro, skParam}:
|
||||
# declarative context, so produce a fresh gensym:
|
||||
result = copySym(result)
|
||||
result.ast = n.sym.ast
|
||||
put(c.p, n.sym, result)
|
||||
# when there is a nested proc inside a template, semtmpl
|
||||
# will assign a wrong owner during the first pass over the
|
||||
# template; we must fix it here: see #909
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ type
|
|||
next*: PProcCon # used for stacking procedure contexts
|
||||
wasForwarded*: bool # whether the current proc has a separate header
|
||||
bracketExpr*: PNode # current bracket expression (for ^ support)
|
||||
mapping*: TIdTable
|
||||
|
||||
TInstantiationPair* = object
|
||||
genericSym*: PSym
|
||||
|
|
@ -147,6 +148,35 @@ proc lastOptionEntry*(c: PContext): POptionEntry =
|
|||
|
||||
proc popProcCon*(c: PContext) {.inline.} = c.p = c.p.next
|
||||
|
||||
proc put*(p: PProcCon; key, val: PSym) =
|
||||
if p.mapping.data == nil: initIdTable(p.mapping)
|
||||
#echo "put into table ", key.info
|
||||
p.mapping.idTablePut(key, val)
|
||||
|
||||
proc get*(p: PProcCon; key: PSym): PSym =
|
||||
if p.mapping.data == nil: return nil
|
||||
result = PSym(p.mapping.idTableGet(key))
|
||||
|
||||
proc getGenSym*(c: PContext; s: PSym): PSym =
|
||||
if sfGenSym notin s.flags: return s
|
||||
var it = c.p
|
||||
while it != nil:
|
||||
result = get(it, s)
|
||||
if result != nil:
|
||||
#echo "got from table ", result.name.s, " ", result.info
|
||||
return result
|
||||
it = it.next
|
||||
result = s
|
||||
|
||||
proc considerGenSyms*(c: PContext; n: PNode) =
|
||||
if n.kind == nkSym:
|
||||
let s = getGenSym(c, n.sym)
|
||||
if n.sym != s:
|
||||
n.sym = s
|
||||
else:
|
||||
for i in 0..<n.safeLen:
|
||||
considerGenSyms(c, n.sons[i])
|
||||
|
||||
proc newOptionEntry*(): POptionEntry =
|
||||
new(result)
|
||||
result.options = gOptions
|
||||
|
|
|
|||
|
|
@ -922,7 +922,8 @@ proc readTypeParameter(c: PContext, typ: PType,
|
|||
return newSymNode(copySym(tParam.sym).linkTo(foundTyp), info)
|
||||
#echo "came here: returned nil"
|
||||
|
||||
proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
|
||||
proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
|
||||
let s = getGenSym(c, sym)
|
||||
case s.kind
|
||||
of skConst:
|
||||
markUsed(n.info, s)
|
||||
|
|
@ -1093,11 +1094,11 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
|||
return readTypeParameter(c, ty, i, n.info)
|
||||
of tyObject, tyTuple:
|
||||
if ty.n != nil and ty.n.kind == nkRecList:
|
||||
for field in ty.n:
|
||||
if field.sym.name == i:
|
||||
n.typ = newTypeWithSons(c, tyFieldAccessor, @[ty, field.sym.typ])
|
||||
n.typ.n = copyTree(n)
|
||||
return n
|
||||
let field = lookupInRecord(ty.n, i)
|
||||
if field != nil:
|
||||
n.typ = newTypeWithSons(c, tyFieldAccessor, @[ty, field.typ])
|
||||
n.typ.n = copyTree(n)
|
||||
return n
|
||||
else:
|
||||
# echo "TYPE FIELD ACCESS"
|
||||
# debug ty
|
||||
|
|
|
|||
|
|
@ -628,7 +628,10 @@ proc getConstExpr(m: PSym, n: PNode): PNode =
|
|||
of {skProc, skMethod}:
|
||||
result = n
|
||||
of skType:
|
||||
result = newSymNodeTypeDesc(s, n.info)
|
||||
# XXX gensym'ed symbols can come here and cannot be resolved. This is
|
||||
# dirty, but correct.
|
||||
if s.typ != nil:
|
||||
result = newSymNodeTypeDesc(s, n.info)
|
||||
of skGenericParam:
|
||||
if s.typ.kind == tyStatic:
|
||||
if s.typ.n != nil:
|
||||
|
|
@ -656,7 +659,7 @@ proc getConstExpr(m: PSym, n: PNode): PNode =
|
|||
localError(a.info, errCannotEvalXBecauseIncompletelyDefined,
|
||||
"sizeof")
|
||||
result = nil
|
||||
elif skipTypes(a.typ, typedescInst).kind in
|
||||
elif skipTypes(a.typ, typedescInst+{tyRange}).kind in
|
||||
IntegralTypes+NilableTypes+{tySet}:
|
||||
#{tyArray,tyObject,tyTuple}:
|
||||
result = newIntNodeT(getSize(a.typ), n)
|
||||
|
|
|
|||
|
|
@ -106,15 +106,18 @@ proc freshGenSyms(n: PNode, owner, orig: PSym, symMap: var TIdTable) =
|
|||
#if n.kind == nkSym and sfGenSym in n.sym.flags:
|
||||
# if n.sym.owner != orig:
|
||||
# echo "symbol ", n.sym.name.s, " orig ", orig, " owner ", n.sym.owner
|
||||
if n.kind == nkSym and {sfGenSym, sfFromGeneric} * n.sym.flags == {sfGenSym}: # and
|
||||
if n.kind == nkSym and sfGenSym in n.sym.flags: # and
|
||||
# (n.sym.owner == orig or n.sym.owner.kind in {skPackage}):
|
||||
let s = n.sym
|
||||
var x = PSym(idTableGet(symMap, s))
|
||||
if x == nil:
|
||||
if x != nil:
|
||||
n.sym = x
|
||||
elif s.owner.kind == skPackage:
|
||||
#echo "copied this ", s.name.s
|
||||
x = copySym(s, false)
|
||||
x.owner = owner
|
||||
idTablePut(symMap, s, x)
|
||||
n.sym = x
|
||||
n.sym = x
|
||||
else:
|
||||
for i in 0 .. <safeLen(n): freshGenSyms(n.sons[i], owner, orig, symMap)
|
||||
|
||||
|
|
|
|||
|
|
@ -1360,6 +1360,7 @@ 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
|
||||
discard semProcAux(c, s.ast, s.kind, {}, stepDetermineType)
|
||||
|
||||
proc semIterator(c: PContext, n: PNode): PNode =
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ proc newGenSym(kind: TSymKind, n: PNode, c: var TemplCtx): PSym =
|
|||
result = newSym(kind, considerQuotedIdent(n), c.owner, n.info)
|
||||
incl(result.flags, sfGenSym)
|
||||
incl(result.flags, sfShadowed)
|
||||
if c.scopeN == 0: incl(result.flags, sfFromGeneric)
|
||||
#if c.scopeN == 0: incl(result.flags, sfFromGeneric)
|
||||
|
||||
proc addLocalDecl(c: var TemplCtx, n: var PNode, k: TSymKind) =
|
||||
# locals default to 'gensym':
|
||||
|
|
|
|||
|
|
@ -297,7 +297,7 @@ proc semOrdinal(c: PContext, n: PNode, prev: PType): PType =
|
|||
|
||||
proc semTypeIdent(c: PContext, n: PNode): PSym =
|
||||
if n.kind == nkSym:
|
||||
result = n.sym
|
||||
result = getGenSym(c, n.sym)
|
||||
else:
|
||||
when defined(nimfix):
|
||||
result = pickSym(c, n, skType)
|
||||
|
|
@ -1319,8 +1319,9 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
|||
prev.id = s.typ.id
|
||||
result = prev
|
||||
of nkSym:
|
||||
if n.sym.kind == skType and n.sym.typ != nil:
|
||||
var t = n.sym.typ
|
||||
let s = getGenSym(c, n.sym)
|
||||
if s.kind == skType and s.typ != nil:
|
||||
var t = s.typ
|
||||
let alias = maybeAliasType(c, t, prev)
|
||||
if alias != nil:
|
||||
result = alias
|
||||
|
|
@ -1332,7 +1333,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
|||
markUsed(n.info, n.sym)
|
||||
styleCheckUse(n.info, n.sym)
|
||||
else:
|
||||
if n.sym.kind != skError: localError(n.info, errTypeExpected)
|
||||
if s.kind != skError: localError(n.info, errTypeExpected)
|
||||
result = newOrPrevType(tyError, prev, c)
|
||||
of nkObjectTy: result = semObjectNode(c, n, prev)
|
||||
of nkTupleTy: result = semTuple(c, n, prev)
|
||||
|
|
|
|||
|
|
@ -1583,12 +1583,14 @@ proc prepareOperand(c: PContext; formal: PType; a: PNode): PNode =
|
|||
result = c.semOperand(c, a, flags)
|
||||
else:
|
||||
result = a
|
||||
considerGenSyms(c, result)
|
||||
|
||||
proc prepareOperand(c: PContext; a: PNode): PNode =
|
||||
if a.typ.isNil:
|
||||
result = c.semOperand(c, a, {efDetermineType})
|
||||
else:
|
||||
result = a
|
||||
considerGenSyms(c, result)
|
||||
|
||||
proc prepareNamedParam(a: PNode) =
|
||||
if a.sons[0].kind != nkIdent:
|
||||
|
|
|
|||
|
|
@ -869,7 +869,12 @@ proc transform(c: PTransf, n: PNode): PTransNode =
|
|||
else:
|
||||
result = transformSons(c, n)
|
||||
of nkIdentDefs, nkConstDef:
|
||||
result = transformSons(c, n)
|
||||
when true:
|
||||
result = transformSons(c, n)
|
||||
else:
|
||||
result = n.PTransNode
|
||||
let L = n.len-1
|
||||
result[L] = transform(c, n.sons[L])
|
||||
# XXX comment handling really sucks:
|
||||
if importantComments():
|
||||
PNode(result).comment = n.comment
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ proc exprStructuralEquivalent*(a, b: PNode; strictSymEquality=false): bool =
|
|||
# don't go nuts here: same symbol as string is enough:
|
||||
result = a.sym.name.id == b.sym.name.id
|
||||
of nkIdent: result = a.ident.id == b.ident.id
|
||||
of nkCharLit..nkInt64Lit: result = a.intVal == b.intVal
|
||||
of nkCharLit..nkUInt64Lit: result = a.intVal == b.intVal
|
||||
of nkFloatLit..nkFloat64Lit: result = a.floatVal == b.floatVal
|
||||
of nkStrLit..nkTripleStrLit: result = a.strVal == b.strVal
|
||||
of nkEmpty, nkNilLit, nkType: result = true
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue