Codegen: use type forward declarations more aggresively. Fixes #7339 (#7340)

Do not emit object definition it if used only by ref or ptr
This commit is contained in:
cooldome 2018-03-16 15:21:03 +00:00 • committed by Andreas Rumpf
commit 70b28a39fe
4 changed files with 32 additions and 1 deletions

View file

@ -1364,6 +1364,7 @@ proc genOf(p: BProc, x: PNode, typ: PType, d: var TLoc) =
if t.kind notin {tyVar, tyLent} or not p.module.compileToCpp: if t.kind notin {tyVar, tyLent} or not p.module.compileToCpp:
r = rfmt(nil, "(*$1)", r) r = rfmt(nil, "(*$1)", r)
t = skipTypes(t.lastSon, typedescInst) t = skipTypes(t.lastSon, typedescInst)
discard getTypeDesc(p.module, t)
if not p.module.compileToCpp: if not p.module.compileToCpp:
while t.kind == tyObject and t.sons[0] != nil: while t.kind == tyObject and t.sons[0] != nil:
add(r, ~".Sup") add(r, ~".Sup")
@ -2062,6 +2063,7 @@ proc upConv(p: BProc, n: PNode, d: var TLoc) =
proc downConv(p: BProc, n: PNode, d: var TLoc) = proc downConv(p: BProc, n: PNode, d: var TLoc) =
if p.module.compileToCpp: if p.module.compileToCpp:
discard getTypeDesc(p.module, skipTypes(n[0].typ, abstractPtrs))
expr(p, n.sons[0], d) # downcast does C++ for us expr(p, n.sons[0], d) # downcast does C++ for us
else: else:
var dest = skipTypes(n.typ, abstractPtrs) var dest = skipTypes(n.typ, abstractPtrs)
@ -2070,6 +2072,7 @@ proc downConv(p: BProc, n: PNode, d: var TLoc) =
while arg.kind == nkObjDownConv: arg = arg.sons[0] while arg.kind == nkObjDownConv: arg = arg.sons[0]
var src = skipTypes(arg.typ, abstractPtrs) var src = skipTypes(arg.typ, abstractPtrs)
discard getTypeDesc(p.module, src)
var a: TLoc var a: TLoc
initLocExpr(p, arg, a) initLocExpr(p, arg, a)
var r = rdLoc(a) var r = rdLoc(a)

View file

@ -368,6 +368,8 @@ proc getTypeForward(m: BModule, typ: PType; sig: SigHash): Rope =
if not isImportedType(concrete): if not isImportedType(concrete):
addf(m.s[cfsForwardTypes], getForwardStructFormat(m), addf(m.s[cfsForwardTypes], getForwardStructFormat(m),
[structOrUnion(typ), result]) [structOrUnion(typ), result])
else:
pushType(m, concrete)
doAssert m.forwTypeCache[sig] == result doAssert m.forwTypeCache[sig] == result
else: internalError("getTypeForward(" & $typ.kind & ')') else: internalError("getTypeForward(" & $typ.kind & ')')
@ -665,7 +667,6 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope =
let name = getTypeForward(m, et, hashType et) let name = getTypeForward(m, et, hashType et)
result = name & star result = name & star
m.typeCache[sig] = result m.typeCache[sig] = result
pushType(m, et)
of tySequence: of tySequence:
# no restriction! We have a forward declaration for structs # no restriction! We have a forward declaration for structs
let name = getTypeForward(m, et, hashType et) let name = getTypeForward(m, et, hashType et)

View file

@ -0,0 +1,12 @@
type
MyRefObject* = ref object
s: string
proc newMyRefObject*(s: string): MyRefObject =
new(result)
result.s = s
proc `$`*(o: MyRefObject): string =
o.s

View file

@ -0,0 +1,15 @@
discard """
ccodecheck: "\\i !@('struct tyObject_MyRefObject'[0-z]+' {')"
output: "hello"
"""
# issue #7339
# Test that MyRefObject is only forward declared as it used only by reference
import mymodule
type AnotherType = object
f: MyRefObject
let x = AnotherType(f: newMyRefObject("hello"))
echo $x.f