Fixes #2617, fixes addr of obj downcast.

This commit is contained in:
yglukhov 2015-06-18 13:35:21 +03:00
commit 9ae4a0425a

View file

@ -33,7 +33,7 @@ import
ast, astalgo, strutils, hashes, trees, platform, magicsys, extccomp, options, ast, astalgo, strutils, hashes, trees, platform, magicsys, extccomp, options,
nversion, nimsets, msgs, securehash, bitsets, idents, lists, types, os, nversion, nimsets, msgs, securehash, bitsets, idents, lists, types, os,
times, ropes, math, passes, ccgutils, wordrecg, renderer, rodread, rodutils, times, ropes, math, passes, ccgutils, wordrecg, renderer, rodread, rodutils,
intsets, cgmeth, lowerings intsets, cgmeth, lowerings, sets
type type
TTarget = enum TTarget = enum
@ -968,7 +968,9 @@ proc genAddr(p: PProc, n: PNode, r: var TCompRes) =
of tyTuple: of tyTuple:
genFieldAddr(p, n.sons[0], r) genFieldAddr(p, n.sons[0], r)
else: internalError(n.sons[0].info, "expr(nkBracketExpr, " & $kindOfIndexedExpr & ')') else: internalError(n.sons[0].info, "expr(nkBracketExpr, " & $kindOfIndexedExpr & ')')
else: internalError(n.sons[0].info, "genAddr") of nkObjDownConv:
gen(p, n.sons[0], r)
else: internalError(n.sons[0].info, "genAddr: " & $n.sons[0].kind)
proc genProcForSymIfNeeded(p: PProc, s: PSym) = proc genProcForSymIfNeeded(p: PProc, s: PSym) =
if not p.g.generatedSyms.containsOrIncl(s.id): if not p.g.generatedSyms.containsOrIncl(s.id):
@ -1096,24 +1098,34 @@ proc putToSeq(s: string, indirect: bool): Rope =
if indirect: result = "[$1]" % [result] if indirect: result = "[$1]" % [result]
proc createVar(p: PProc, typ: PType, indirect: bool): Rope proc createVar(p: PProc, typ: PType, indirect: bool): Rope
proc createRecordVarAux(p: PProc, rec: PNode, c: var int): Rope = proc createRecordVarAux(p: PProc, rec: PNode, excludeMembers: HashSet[string], output: var Rope) =
result = nil
case rec.kind case rec.kind
of nkRecList: of nkRecList:
for i in countup(0, sonsLen(rec) - 1): for i in countup(0, sonsLen(rec) - 1):
add(result, createRecordVarAux(p, rec.sons[i], c)) createRecordVarAux(p, rec.sons[i], excludeMembers, output)
of nkRecCase: of nkRecCase:
add(result, createRecordVarAux(p, rec.sons[0], c)) createRecordVarAux(p, rec.sons[0], excludeMembers, output)
for i in countup(1, sonsLen(rec) - 1): for i in countup(1, sonsLen(rec) - 1):
add(result, createRecordVarAux(p, lastSon(rec.sons[i]), c)) createRecordVarAux(p, lastSon(rec.sons[i]), excludeMembers, output)
of nkSym: of nkSym:
if c > 0: add(result, ", ") let name = $mangleName(rec.sym)
add(result, mangleName(rec.sym)) if not (name in excludeMembers):
add(result, ": ") if output.len > 0: output.add(", ")
add(result, createVar(p, rec.sym.typ, false)) output.add(name)
inc(c) output.add(": ")
output.add(createVar(p, rec.sym.typ, false))
else: internalError(rec.info, "createRecordVarAux") else: internalError(rec.info, "createRecordVarAux")
proc createObjInitList(p: PProc, typ: PType, excludeMembers: HashSet[string], output: var Rope) =
var t = typ
if tfFinal notin t.flags or t.sons[0] != nil:
if not ("m_type" in excludeMembers):
if output.len > 0: output.add(", ")
addf(output, "m_type: $1" | "m_type = $#", [genTypeInfo(p, t)])
while t != nil:
createRecordVarAux(p, t.n, excludeMembers, output)
t = t.sons[0]
proc createVar(p: PProc, typ: PType, indirect: bool): Rope = proc createVar(p: PProc, typ: PType, indirect: bool): Rope =
var t = skipTypes(typ, abstractInst) var t = skipTypes(typ, abstractInst)
case t.kind case t.kind
@ -1154,15 +1166,10 @@ proc createVar(p: PProc, typ: PType, indirect: bool): Rope =
add(result, "}") add(result, "}")
if indirect: result = "[$1]" % [result] if indirect: result = "[$1]" % [result]
of tyObject: of tyObject:
result = rope("{") var emptySet = initSet[string](2)
var c = 0 var initList : Rope
if tfFinal notin t.flags or t.sons[0] != nil: createObjInitList(p, t, emptySet, initList)
inc(c) result = "{$1}" % [initList]
addf(result, "m_type: $1" | "m_type = $#", [genTypeInfo(p, t)])
while t != nil:
add(result, createRecordVarAux(p, t.n, c))
t = t.sons[0]
add(result, "}")
if indirect: result = "[$1]" % [result] if indirect: result = "[$1]" % [result]
of tyVar, tyPtr, tyRef: of tyVar, tyPtr, tyRef:
if mapType(t) == etyBaseIndex: if mapType(t) == etyBaseIndex:
@ -1435,6 +1442,7 @@ proc genObjConstr(p: PProc, n: PNode, r: var TCompRes) =
var a: TCompRes var a: TCompRes
r.res = rope("{") r.res = rope("{")
r.kind = resExpr r.kind = resExpr
var fieldNames = initSet[string]()
for i in countup(1, sonsLen(n) - 1): for i in countup(1, sonsLen(n) - 1):
if i > 1: add(r.res, ", ") if i > 1: add(r.res, ", ")
var it = n.sons[i] var it = n.sons[i]
@ -1442,7 +1450,10 @@ proc genObjConstr(p: PProc, n: PNode, r: var TCompRes) =
gen(p, it.sons[1], a) gen(p, it.sons[1], a)
var f = it.sons[0].sym var f = it.sons[0].sym
if f.loc.r == nil: f.loc.r = mangleName(f) if f.loc.r == nil: f.loc.r = mangleName(f)
fieldNames.incl($f.loc.r)
addf(r.res, "$#: $#" | "$# = $#" , [f.loc.r, a.res]) addf(r.res, "$#: $#" | "$# = $#" , [f.loc.r, a.res])
let t = skipTypes(n.typ, abstractInst + skipPtrs)
createObjInitList(p, t, fieldNames, r.res)
r.res.add("}") r.res.add("}")
proc genConv(p: PProc, n: PNode, r: var TCompRes) = proc genConv(p: PProc, n: PNode, r: var TCompRes) =