bugfix: typeinfo generation for tuples
This commit is contained in:
parent
849208d779
commit
18bec94e22
7 changed files with 82 additions and 41 deletions
|
|
@ -641,20 +641,16 @@ proc genObjectInfo(m: BModule, typ: PType, name: PRope) =
|
|||
genObjectFields(m, typ, typ.n, tmp)
|
||||
appf(m.s[cfsTypeInit3], "$1->node = &$2;$n", [name, tmp])
|
||||
|
||||
proc genTupleInfo(m: BModule, typ: PType, name: PRope) =
|
||||
var
|
||||
tmp, expr, tmp2: PRope
|
||||
length: int
|
||||
a: PType
|
||||
proc genTupleInfo(m: BModule, typ: PType, name: PRope) =
|
||||
genTypeInfoAuxBase(m, typ, name, toRope("0"))
|
||||
expr = getNimNode(m)
|
||||
length = sonsLen(typ)
|
||||
var expr = getNimNode(m)
|
||||
var length = sonsLen(typ)
|
||||
if length > 0:
|
||||
tmp = getTempName()
|
||||
var tmp = getTempName()
|
||||
appf(m.s[cfsTypeInit1], "static TNimNode* $1[$2];$n", [tmp, toRope(length)])
|
||||
for i in countup(0, length - 1):
|
||||
a = typ.sons[i]
|
||||
tmp2 = getNimNode(m)
|
||||
var a = typ.sons[i]
|
||||
var tmp2 = getNimNode(m)
|
||||
appf(m.s[cfsTypeInit3], "$1[$2] = &$3;$n", [tmp, toRope(i), tmp2])
|
||||
appf(m.s[cfsTypeInit3], "$1.kind = 1;$n" &
|
||||
"$1.offset = offsetof($2, Field$3);$n" & "$1.typ = $4;$n" &
|
||||
|
|
@ -665,7 +661,7 @@ proc genTupleInfo(m: BModule, typ: PType, name: PRope) =
|
|||
else:
|
||||
appf(m.s[cfsTypeInit3], "$1.len = $2; $1.kind = 2;$n",
|
||||
[expr, toRope(length)])
|
||||
appf(m.s[cfsTypeInit3], "$1->node = &$2;$n", [name, tmp])
|
||||
appf(m.s[cfsTypeInit3], "$1->node = &$2;$n", [name, expr])
|
||||
|
||||
proc genEnumInfo(m: BModule, typ: PType, name: PRope) =
|
||||
# Type information for enumerations is quite heavy, so we do some
|
||||
|
|
|
|||
|
|
@ -36,9 +36,8 @@ proc GenericCacheGet(c: PContext, genericSym, instSym: PSym): PSym =
|
|||
var a = c.generics.sons[i].sons[0].sym
|
||||
if genericSym.id == a.id:
|
||||
var b = c.generics.sons[i].sons[1].sym
|
||||
if equalParams(b.typ.n, instSym.typ.n) == paramsEqual:
|
||||
#if gVerbosity > 0 then
|
||||
# MessageOut('found in cache: ' + getProcHeader(instSym));
|
||||
if equalParams(b.typ.n, instSym.typ.n) == paramsEqual:
|
||||
#echo "found in cache: ", getProcHeader(instSym)
|
||||
return b
|
||||
|
||||
proc GenericCacheAdd(c: PContext, genericSym, instSym: PSym) =
|
||||
|
|
@ -66,20 +65,17 @@ proc removeDefaultParamValues(n: PNode) =
|
|||
proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
|
||||
info: TLineInfo): PSym =
|
||||
# generates an instantiated proc
|
||||
var
|
||||
oldPrc, oldMod: PSym
|
||||
n: PNode
|
||||
if c.InstCounter > 1000: InternalError(fn.ast.info, "nesting too deep")
|
||||
inc(c.InstCounter)
|
||||
# NOTE: for access of private fields within generics from a different module
|
||||
# and other identifiers we fake the current module temporarily!
|
||||
# XXX bad hack!
|
||||
oldMod = c.module
|
||||
var oldMod = c.module
|
||||
c.module = getModule(fn)
|
||||
result = copySym(fn, false)
|
||||
incl(result.flags, sfFromGeneric)
|
||||
result.owner = getCurrOwner().owner
|
||||
n = copyTree(fn.ast)
|
||||
var n = copyTree(fn.ast)
|
||||
result.ast = n
|
||||
pushOwner(result)
|
||||
openScope(c.tab)
|
||||
|
|
@ -98,7 +94,7 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
|
|||
result.typ = newTypeS(tyProc, c)
|
||||
addSon(result.typ, nil)
|
||||
result.typ.callConv = fn.typ.callConv
|
||||
oldPrc = GenericCacheGet(c, fn, result)
|
||||
var oldPrc = GenericCacheGet(c, fn, result)
|
||||
if oldPrc == nil:
|
||||
# add it here, so that recursive generic procs are possible:
|
||||
GenericCacheAdd(c, fn, result)
|
||||
|
|
@ -110,6 +106,7 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
|
|||
addResultNode(c, n)
|
||||
n.sons[codePos] = semStmtScope(c, n.sons[codePos])
|
||||
popProcCon(c)
|
||||
#echo "code instantiated ", result.name.s
|
||||
else:
|
||||
result = oldPrc
|
||||
popInfoContext()
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ proc containsGenericType*(t: PType): bool =
|
|||
proc searchInstTypes(tab: TIdTable, key: PType): PType =
|
||||
# returns nil if we need to declare this type
|
||||
result = PType(IdTableGet(tab, key))
|
||||
if (result == nil) and (tab.counter > 0):
|
||||
if result == nil and tab.counter > 0:
|
||||
# we have to do a slow linear search because types may need
|
||||
# to be compared by their structure:
|
||||
for h in countup(0, high(tab.data)):
|
||||
|
|
@ -127,13 +127,13 @@ proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType =
|
|||
of tyGenericBody:
|
||||
InternalError(cl.info, "ReplaceTypeVarsT: tyGenericBody")
|
||||
result = ReplaceTypeVarsT(cl, lastSon(t))
|
||||
else:
|
||||
if containsGenericType(t):
|
||||
else:
|
||||
if containsGenericType(t):
|
||||
result = copyType(t, t.owner, false)
|
||||
for i in countup(0, sonsLen(result) - 1):
|
||||
for i in countup(0, sonsLen(result) - 1):
|
||||
result.sons[i] = ReplaceTypeVarsT(cl, result.sons[i])
|
||||
result.n = ReplaceTypeVarsN(cl, result.n)
|
||||
if result.Kind in GenericTypes:
|
||||
if result.Kind in GenericTypes:
|
||||
LocalError(cl.info, errCannotInstantiateX, TypeToString(t, preferName))
|
||||
#writeln(output, ropeToStr(Typetoyaml(result)))
|
||||
#checkConstructedType(cl.info, result)
|
||||
|
|
|
|||
|
|
@ -514,10 +514,10 @@ proc transformFor(c: PTransf, n: PNode): PTransNode =
|
|||
popTransCon(c)
|
||||
|
||||
proc getMagicOp(call: PNode): TMagic =
|
||||
if (call.sons[0].kind == nkSym) and
|
||||
(call.sons[0].sym.kind in {skProc, skMethod, skConverter}):
|
||||
if call.sons[0].kind == nkSym and
|
||||
call.sons[0].sym.kind in {skProc, skMethod, skConverter}:
|
||||
result = call.sons[0].sym.magic
|
||||
else:
|
||||
else:
|
||||
result = mNone
|
||||
|
||||
proc gatherVars(c: PTransf, n: PNode, marked: var TIntSet, owner: PSym,
|
||||
|
|
@ -528,10 +528,10 @@ proc gatherVars(c: PTransf, n: PNode, marked: var TIntSet, owner: PSym,
|
|||
var s = n.sym
|
||||
var found = false
|
||||
case s.kind
|
||||
of skVar: found = not (sfGlobal in s.flags)
|
||||
of skVar: found = sfGlobal notin s.flags
|
||||
of skTemp, skForVar, skParam: found = true
|
||||
else: nil
|
||||
if found and (owner.id != s.owner.id) and not ContainsOrIncl(marked, s.id):
|
||||
if found and owner.id != s.owner.id and not ContainsOrIncl(marked, s.id):
|
||||
incl(s.flags, sfInClosure)
|
||||
addSon(container, copyNode(n)) # DON'T make a copy of the symbol!
|
||||
of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit:
|
||||
|
|
@ -559,7 +559,7 @@ proc indirectAccess(a, b: PSym): PNode =
|
|||
proc transformLambda(c: PTransf, n: PNode): PNode =
|
||||
var marked = initIntSet()
|
||||
result = n
|
||||
if (n.sons[namePos].kind != nkSym): InternalError(n.info, "transformLambda")
|
||||
if n.sons[namePos].kind != nkSym: InternalError(n.info, "transformLambda")
|
||||
var s = n.sons[namePos].sym
|
||||
var closure = newNodeI(nkRecList, n.sons[codePos].info)
|
||||
gatherVars(c, n.sons[codePos], marked, s, closure)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue