diff options
-rw-r--r-- | compiler/ccgexprs.nim | 44 | ||||
-rw-r--r-- | compiler/cgen.nim | 5 | ||||
-rw-r--r-- | compiler/semstmts.nim | 2 | ||||
-rw-r--r-- | tests/cpp/tconstructor.nim | 35 |
4 files changed, 66 insertions, 20 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index d1c0ac7b1..4521664bf 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -1494,8 +1494,27 @@ proc handleConstExpr(p: BProc, n: PNode, d: var TLoc): bool = else: result = false + +proc genFieldObjConstr(p: BProc; ty: PType; useTemp, isRef: bool; nField, val, check: PNode; d: var TLoc; r: Rope; info: TLineInfo) = + var tmp2: TLoc = default(TLoc) + tmp2.r = r + let field = lookupFieldAgain(p, ty, nField.sym, tmp2.r) + if field.loc.r == "": fillObjectFields(p.module, ty) + if field.loc.r == "": internalError(p.config, info, "genFieldObjConstr") + if check != nil and optFieldCheck in p.options: + genFieldCheck(p, check, r, field) + tmp2.r.add(".") + tmp2.r.add(field.loc.r) + if useTemp: + tmp2.k = locTemp + tmp2.storage = if isRef: OnHeap else: OnStack + else: + tmp2.k = d.k + tmp2.storage = if isRef: OnHeap else: d.storage + tmp2.lode = val + expr(p, val, tmp2) + proc genObjConstr(p: BProc, e: PNode, d: var TLoc) = - #echo renderTree e, " ", e.isDeepConstExpr # inheritance in C++ does not allow struct initialization so # we skip this step here: if not p.module.compileToCpp and optSeqDestructors notin p.config.globalOptions: @@ -1534,24 +1553,11 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) = discard getTypeDesc(p.module, t) let ty = getUniqueType(t) for i in 1..<e.len: - let it = e[i] - var tmp2: TLoc = default(TLoc) - tmp2.r = r - let field = lookupFieldAgain(p, ty, it[0].sym, tmp2.r) - if field.loc.r == "": fillObjectFields(p.module, ty) - if field.loc.r == "": internalError(p.config, e.info, "genObjConstr") - if it.len == 3 and optFieldCheck in p.options: - genFieldCheck(p, it[2], r, field) - tmp2.r.add(".") - tmp2.r.add(field.loc.r) - if useTemp: - tmp2.k = locTemp - tmp2.storage = if isRef: OnHeap else: OnStack - else: - tmp2.k = d.k - tmp2.storage = if isRef: OnHeap else: d.storage - tmp2.lode = it[1] - expr(p, it[1], tmp2) + var check: PNode = nil + if e[i].len == 3 and optFieldCheck in p.options: + check = e[i][2] + genFieldObjConstr(p, ty, useTemp, isRef, e[i][0], e[i][1], check, d, r, e.info) + if useTemp: if d.k == locNone: d = tmp diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 678a15bc9..f8d62e1af 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -1171,6 +1171,11 @@ proc genProcAux*(m: BModule, prc: PSym) = returnStmt = ropecg(p.module, "\treturn $1;$n", [rdLoc(res.loc)]) elif sfConstructor in prc.flags: fillLoc(resNode.sym.loc, locParam, resNode, "this", OnHeap) + let ty = resNode.sym.typ[0] #generate nim's ctor + for i in 1..<resNode.sym.ast.len: + let field = resNode.sym.ast[i] + genFieldObjConstr(p, ty, useTemp = false, isRef = false, + field[0], field[1], check = nil, resNode.sym.loc, "(*this)", tmpInfo) else: fillResult(p.config, resNode, prc.typ) assignParam(p, res, prc.typ[0]) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 08d6d44e6..5a72632ef 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -1711,6 +1711,8 @@ proc addThis(c: PContext, n: PNode, t: PType, owner: TSymKind) = c.p.resultSym = s n.add newSymNode(c.p.resultSym) addParamOrResult(c, c.p.resultSym, owner) + #resolves nim's obj ctor inside cpp ctors see #22669 + s.ast = c.semExpr(c, newTree(nkCall, t[0].sym.ast[0])) proc addResult(c: PContext, n: PNode, t: PType, owner: TSymKind) = template genResSym(s) = diff --git a/tests/cpp/tconstructor.nim b/tests/cpp/tconstructor.nim index b69162661..32fb5e1a2 100644 --- a/tests/cpp/tconstructor.nim +++ b/tests/cpp/tconstructor.nim @@ -7,6 +7,15 @@ discard """ 123 0 123 +___ +0 +777 +10 +123 +0 +777 +10 +123 ''' """ @@ -73,4 +82,28 @@ proc main = n.x = 123 echo n.x -main() \ No newline at end of file +main() +#bug: +echo "___" +type + NimClassWithDefault = object + x: int + y = 777 + case kind: bool = true + of true: + z: int = 10 + else: discard + +proc makeNimClassWithDefault(): NimClassWithDefault {.constructor.} = + discard + +proc init = + for i in 0 .. 1: + var n = makeNimClassWithDefault() + echo n.x + echo n.y + echo n.z + n.x = 123 + echo n.x + +init() \ No newline at end of file |