diff options
author | cooldome <cdome@bk.ru> | 2018-03-16 15:21:03 +0000 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2018-03-16 16:21:03 +0100 |
commit | 70b28a39fedfe030ac4e1615d32328d7ffd3f79d (patch) | |
tree | e1a382756971f788634e9d82d79a06b5c10250e0 | |
parent | a9f21cffdf7304272b5bbabeabec4a3e659819fa (diff) | |
download | Nim-70b28a39fedfe030ac4e1615d32328d7ffd3f79d.tar.gz |
Codegen: use type forward declarations more aggresively. Fixes #7339 (#7340)
Do not emit object definition it if used only by ref or ptr
-rw-r--r-- | compiler/ccgexprs.nim | 3 | ||||
-rw-r--r-- | compiler/ccgtypes.nim | 3 | ||||
-rw-r--r-- | tests/ccgbugs/mymodule.nim | 12 | ||||
-rw-r--r-- | tests/ccgbugs/tforward_decl_only.nim | 15 |
4 files changed, 32 insertions, 1 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 998220469..060a5fdbd 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -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: r = rfmt(nil, "(*$1)", r) t = skipTypes(t.lastSon, typedescInst) + discard getTypeDesc(p.module, t) if not p.module.compileToCpp: while t.kind == tyObject and t.sons[0] != nil: 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) = if p.module.compileToCpp: + discard getTypeDesc(p.module, skipTypes(n[0].typ, abstractPtrs)) expr(p, n.sons[0], d) # downcast does C++ for us else: 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] var src = skipTypes(arg.typ, abstractPtrs) + discard getTypeDesc(p.module, src) var a: TLoc initLocExpr(p, arg, a) var r = rdLoc(a) diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index bdba34e36..4fc029116 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -368,6 +368,8 @@ proc getTypeForward(m: BModule, typ: PType; sig: SigHash): Rope = if not isImportedType(concrete): addf(m.s[cfsForwardTypes], getForwardStructFormat(m), [structOrUnion(typ), result]) + else: + pushType(m, concrete) doAssert m.forwTypeCache[sig] == result 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) result = name & star m.typeCache[sig] = result - pushType(m, et) of tySequence: # no restriction! We have a forward declaration for structs let name = getTypeForward(m, et, hashType et) diff --git a/tests/ccgbugs/mymodule.nim b/tests/ccgbugs/mymodule.nim new file mode 100644 index 000000000..d3306ec49 --- /dev/null +++ b/tests/ccgbugs/mymodule.nim @@ -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 + \ No newline at end of file diff --git a/tests/ccgbugs/tforward_decl_only.nim b/tests/ccgbugs/tforward_decl_only.nim new file mode 100644 index 000000000..dcd74eaf4 --- /dev/null +++ b/tests/ccgbugs/tforward_decl_only.nim @@ -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 + |