mirror of
https://github.com/nim-lang/Nim.git
synced 2026-07-30 12:17:56 +00:00
fixes #22669 constructor pragma doesnt init Nim default fields --------- Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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])
|
||||
|
||||
@@ -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) =
|
||||
|
||||
Reference in New Issue
Block a user