backend preparations for incomplete/forwarded object types
This commit is contained in:
parent
dcfc2b0e5f
commit
c6235920cb
10 changed files with 122 additions and 90 deletions
|
|
@ -1665,3 +1665,8 @@ when false:
|
||||||
if n[i].containsNil: return true
|
if n[i].containsNil: return true
|
||||||
|
|
||||||
template hasDestructor*(t: PType): bool = tfHasAsgn in t.flags
|
template hasDestructor*(t: PType): bool = tfHasAsgn in t.flags
|
||||||
|
template incompleteType*(t: PType): bool =
|
||||||
|
t.sym != nil and {sfForward, sfNoForward} * t.sym.flags == {sfForward}
|
||||||
|
|
||||||
|
template typeCompleted*(t: PType) =
|
||||||
|
incl t.sym.flags, sfNoForward
|
||||||
|
|
|
||||||
|
|
@ -270,10 +270,10 @@ proc genGenericAsgn(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
||||||
addrLoc(dest), addrLoc(src), rdLoc(dest))
|
addrLoc(dest), addrLoc(src), rdLoc(dest))
|
||||||
else:
|
else:
|
||||||
linefmt(p, cpsStmts, "#genericShallowAssign((void*)$1, (void*)$2, $3);$n",
|
linefmt(p, cpsStmts, "#genericShallowAssign((void*)$1, (void*)$2, $3);$n",
|
||||||
addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t))
|
addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t, dest.lode.info))
|
||||||
else:
|
else:
|
||||||
linefmt(p, cpsStmts, "#genericAssign((void*)$1, (void*)$2, $3);$n",
|
linefmt(p, cpsStmts, "#genericAssign((void*)$1, (void*)$2, $3);$n",
|
||||||
addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t))
|
addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t, dest.lode.info))
|
||||||
|
|
||||||
proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
||||||
# This function replaces all other methods for generating
|
# This function replaces all other methods for generating
|
||||||
|
|
@ -291,7 +291,8 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
||||||
genRefAssign(p, dest, src, flags)
|
genRefAssign(p, dest, src, flags)
|
||||||
else:
|
else:
|
||||||
linefmt(p, cpsStmts, "#genericSeqAssign($1, $2, $3);$n",
|
linefmt(p, cpsStmts, "#genericSeqAssign($1, $2, $3);$n",
|
||||||
addrLoc(dest), rdLoc(src), genTypeInfo(p.module, dest.t))
|
addrLoc(dest), rdLoc(src),
|
||||||
|
genTypeInfo(p.module, dest.t, dest.lode.info))
|
||||||
of tyString:
|
of tyString:
|
||||||
if (needToCopy notin flags and src.storage != OnStatic) or canMove(src.lode):
|
if (needToCopy notin flags and src.storage != OnStatic) or canMove(src.lode):
|
||||||
genRefAssign(p, dest, src, flags)
|
genRefAssign(p, dest, src, flags)
|
||||||
|
|
@ -352,7 +353,8 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
||||||
if needsComplexAssignment(dest.t):
|
if needsComplexAssignment(dest.t):
|
||||||
linefmt(p, cpsStmts, # XXX: is this correct for arrays?
|
linefmt(p, cpsStmts, # XXX: is this correct for arrays?
|
||||||
"#genericAssignOpenArray((void*)$1, (void*)$2, $1Len_0, $3);$n",
|
"#genericAssignOpenArray((void*)$1, (void*)$2, $1Len_0, $3);$n",
|
||||||
addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t))
|
addrLoc(dest), addrLoc(src),
|
||||||
|
genTypeInfo(p.module, dest.t, dest.lode.info))
|
||||||
else:
|
else:
|
||||||
useStringh(p.module)
|
useStringh(p.module)
|
||||||
linefmt(p, cpsStmts,
|
linefmt(p, cpsStmts,
|
||||||
|
|
@ -393,14 +395,17 @@ proc genDeepCopy(p: BProc; dest, src: TLoc) =
|
||||||
of tyPtr, tyRef, tyProc, tyTuple, tyObject, tyArray:
|
of tyPtr, tyRef, tyProc, tyTuple, tyObject, tyArray:
|
||||||
# XXX optimize this
|
# XXX optimize this
|
||||||
linefmt(p, cpsStmts, "#genericDeepCopy((void*)$1, (void*)$2, $3);$n",
|
linefmt(p, cpsStmts, "#genericDeepCopy((void*)$1, (void*)$2, $3);$n",
|
||||||
addrLoc(dest), addrLocOrTemp(src), genTypeInfo(p.module, dest.t))
|
addrLoc(dest), addrLocOrTemp(src),
|
||||||
|
genTypeInfo(p.module, dest.t, dest.lode.info))
|
||||||
of tySequence, tyString:
|
of tySequence, tyString:
|
||||||
linefmt(p, cpsStmts, "#genericSeqDeepCopy($1, $2, $3);$n",
|
linefmt(p, cpsStmts, "#genericSeqDeepCopy($1, $2, $3);$n",
|
||||||
addrLoc(dest), rdLoc(src), genTypeInfo(p.module, dest.t))
|
addrLoc(dest), rdLoc(src),
|
||||||
|
genTypeInfo(p.module, dest.t, dest.lode.info))
|
||||||
of tyOpenArray, tyVarargs:
|
of tyOpenArray, tyVarargs:
|
||||||
linefmt(p, cpsStmts,
|
linefmt(p, cpsStmts,
|
||||||
"#genericDeepCopyOpenArray((void*)$1, (void*)$2, $1Len_0, $3);$n",
|
"#genericDeepCopyOpenArray((void*)$1, (void*)$2, $1Len_0, $3);$n",
|
||||||
addrLoc(dest), addrLocOrTemp(src), genTypeInfo(p.module, dest.t))
|
addrLoc(dest), addrLocOrTemp(src),
|
||||||
|
genTypeInfo(p.module, dest.t, dest.lode.info))
|
||||||
of tySet:
|
of tySet:
|
||||||
if mapType(ty) == ctArray:
|
if mapType(ty) == ctArray:
|
||||||
useStringh(p.module)
|
useStringh(p.module)
|
||||||
|
|
@ -1101,7 +1106,8 @@ proc genReset(p: BProc, n: PNode) =
|
||||||
var a: TLoc
|
var a: TLoc
|
||||||
initLocExpr(p, n.sons[1], a)
|
initLocExpr(p, n.sons[1], a)
|
||||||
linefmt(p, cpsStmts, "#genericReset((void*)$1, $2);$n",
|
linefmt(p, cpsStmts, "#genericReset((void*)$1, $2);$n",
|
||||||
addrLoc(a), genTypeInfo(p.module, skipTypes(a.t, {tyVar})))
|
addrLoc(a),
|
||||||
|
genTypeInfo(p.module, skipTypes(a.t, {tyVar}), n.info))
|
||||||
|
|
||||||
proc rawGenNew(p: BProc, a: TLoc, sizeExpr: Rope) =
|
proc rawGenNew(p: BProc, a: TLoc, sizeExpr: Rope) =
|
||||||
var sizeExpr = sizeExpr
|
var sizeExpr = sizeExpr
|
||||||
|
|
@ -1115,7 +1121,7 @@ proc rawGenNew(p: BProc, a: TLoc, sizeExpr: Rope) =
|
||||||
sizeExpr = "sizeof($1)" %
|
sizeExpr = "sizeof($1)" %
|
||||||
[getTypeDesc(p.module, bt)]
|
[getTypeDesc(p.module, bt)]
|
||||||
let args = [getTypeDesc(p.module, typ),
|
let args = [getTypeDesc(p.module, typ),
|
||||||
genTypeInfo(p.module, typ),
|
genTypeInfo(p.module, typ, a.lode.info),
|
||||||
sizeExpr]
|
sizeExpr]
|
||||||
if a.storage == OnHeap and usesNativeGC():
|
if a.storage == OnHeap and usesNativeGC():
|
||||||
# use newObjRC1 as an optimization
|
# use newObjRC1 as an optimization
|
||||||
|
|
@ -1145,7 +1151,7 @@ proc genNew(p: BProc, e: PNode) =
|
||||||
proc genNewSeqAux(p: BProc, dest: TLoc, length: Rope) =
|
proc genNewSeqAux(p: BProc, dest: TLoc, length: Rope) =
|
||||||
let seqtype = skipTypes(dest.t, abstractVarRange)
|
let seqtype = skipTypes(dest.t, abstractVarRange)
|
||||||
let args = [getTypeDesc(p.module, seqtype),
|
let args = [getTypeDesc(p.module, seqtype),
|
||||||
genTypeInfo(p.module, seqtype), length]
|
genTypeInfo(p.module, seqtype, dest.lode.info), length]
|
||||||
var call: TLoc
|
var call: TLoc
|
||||||
initLoc(call, locExpr, dest.lode, OnHeap)
|
initLoc(call, locExpr, dest.lode, OnHeap)
|
||||||
if dest.storage == OnHeap and usesNativeGC():
|
if dest.storage == OnHeap and usesNativeGC():
|
||||||
|
|
@ -1173,7 +1179,7 @@ proc genNewSeqOfCap(p: BProc; e: PNode; d: var TLoc) =
|
||||||
putIntoDest(p, d, e, ropecg(p.module,
|
putIntoDest(p, d, e, ropecg(p.module,
|
||||||
"($1)#nimNewSeqOfCap($2, $3)", [
|
"($1)#nimNewSeqOfCap($2, $3)", [
|
||||||
getTypeDesc(p.module, seqtype),
|
getTypeDesc(p.module, seqtype),
|
||||||
genTypeInfo(p.module, seqtype), a.rdLoc]))
|
genTypeInfo(p.module, seqtype, e.info), a.rdLoc]))
|
||||||
gcUsage(e)
|
gcUsage(e)
|
||||||
|
|
||||||
proc genConstExpr(p: BProc, n: PNode): Rope
|
proc genConstExpr(p: BProc, n: PNode): Rope
|
||||||
|
|
@ -1290,7 +1296,7 @@ proc genNewFinalize(p: BProc, e: PNode) =
|
||||||
initLocExpr(p, e.sons[1], a)
|
initLocExpr(p, e.sons[1], a)
|
||||||
initLocExpr(p, e.sons[2], f)
|
initLocExpr(p, e.sons[2], f)
|
||||||
initLoc(b, locExpr, a.lode, OnHeap)
|
initLoc(b, locExpr, a.lode, OnHeap)
|
||||||
ti = genTypeInfo(p.module, refType)
|
ti = genTypeInfo(p.module, refType, e.info)
|
||||||
addf(p.module.s[cfsTypeInit3], "$1->finalizer = (void*)$2;$n", [ti, rdLoc(f)])
|
addf(p.module.s[cfsTypeInit3], "$1->finalizer = (void*)$2;$n", [ti, rdLoc(f)])
|
||||||
b.r = ropecg(p.module, "($1) #newObj($2, sizeof($3))", [
|
b.r = ropecg(p.module, "($1) #newObj($2, sizeof($3))", [
|
||||||
getTypeDesc(p.module, refType),
|
getTypeDesc(p.module, refType),
|
||||||
|
|
@ -1300,10 +1306,10 @@ proc genNewFinalize(p: BProc, e: PNode) =
|
||||||
genObjectInit(p, cpsStmts, bt, a, false)
|
genObjectInit(p, cpsStmts, bt, a, false)
|
||||||
gcUsage(e)
|
gcUsage(e)
|
||||||
|
|
||||||
proc genOfHelper(p: BProc; dest: PType; a: Rope): Rope =
|
proc genOfHelper(p: BProc; dest: PType; a: Rope; info: TLineInfo): Rope =
|
||||||
# unfortunately 'genTypeInfo' sets tfObjHasKids as a side effect, so we
|
# unfortunately 'genTypeInfo' sets tfObjHasKids as a side effect, so we
|
||||||
# have to call it here first:
|
# have to call it here first:
|
||||||
let ti = genTypeInfo(p.module, dest)
|
let ti = genTypeInfo(p.module, dest, info)
|
||||||
if tfFinal in dest.flags or (objHasKidsValid in p.module.flags and
|
if tfFinal in dest.flags or (objHasKidsValid in p.module.flags and
|
||||||
tfObjHasKids notin dest.flags):
|
tfObjHasKids notin dest.flags):
|
||||||
result = "$1.m_type == $2" % [a, ti]
|
result = "$1.m_type == $2" % [a, ti]
|
||||||
|
|
@ -1316,7 +1322,7 @@ proc genOfHelper(p: BProc; dest: PType; a: Rope): Rope =
|
||||||
when false:
|
when false:
|
||||||
# former version:
|
# former version:
|
||||||
result = rfmt(p.module, "#isObj($1.m_type, $2)",
|
result = rfmt(p.module, "#isObj($1.m_type, $2)",
|
||||||
a, genTypeInfo(p.module, dest))
|
a, genTypeInfo(p.module, dest, info))
|
||||||
|
|
||||||
proc genOf(p: BProc, x: PNode, typ: PType, d: var TLoc) =
|
proc genOf(p: BProc, x: PNode, typ: PType, d: var TLoc) =
|
||||||
var a: TLoc
|
var a: TLoc
|
||||||
|
|
@ -1338,9 +1344,9 @@ proc genOf(p: BProc, x: PNode, typ: PType, d: var TLoc) =
|
||||||
globalError(x.info, errGenerated,
|
globalError(x.info, errGenerated,
|
||||||
"no 'of' operator available for pure objects")
|
"no 'of' operator available for pure objects")
|
||||||
if nilCheck != nil:
|
if nilCheck != nil:
|
||||||
r = rfmt(p.module, "(($1) && ($2))", nilCheck, genOfHelper(p, dest, r))
|
r = rfmt(p.module, "(($1) && ($2))", nilCheck, genOfHelper(p, dest, r, x.info))
|
||||||
else:
|
else:
|
||||||
r = rfmt(p.module, "($1)", genOfHelper(p, dest, r))
|
r = rfmt(p.module, "($1)", genOfHelper(p, dest, r, x.info))
|
||||||
putIntoDest(p, d, x, r, a.storage)
|
putIntoDest(p, d, x, r, a.storage)
|
||||||
|
|
||||||
proc genOf(p: BProc, n: PNode, d: var TLoc) =
|
proc genOf(p: BProc, n: PNode, d: var TLoc) =
|
||||||
|
|
@ -1363,12 +1369,12 @@ proc genRepr(p: BProc, e: PNode, d: var TLoc) =
|
||||||
of tyEnum, tyOrdinal:
|
of tyEnum, tyOrdinal:
|
||||||
putIntoDest(p, d, e,
|
putIntoDest(p, d, e,
|
||||||
ropecg(p.module, "#reprEnum((NI)$1, $2)", [
|
ropecg(p.module, "#reprEnum((NI)$1, $2)", [
|
||||||
rdLoc(a), genTypeInfo(p.module, t)]), a.storage)
|
rdLoc(a), genTypeInfo(p.module, t, e.info)]), a.storage)
|
||||||
of tyString:
|
of tyString:
|
||||||
putIntoDest(p, d, e, ropecg(p.module, "#reprStr($1)", [rdLoc(a)]), a.storage)
|
putIntoDest(p, d, e, ropecg(p.module, "#reprStr($1)", [rdLoc(a)]), a.storage)
|
||||||
of tySet:
|
of tySet:
|
||||||
putIntoDest(p, d, e, ropecg(p.module, "#reprSet($1, $2)", [
|
putIntoDest(p, d, e, ropecg(p.module, "#reprSet($1, $2)", [
|
||||||
addrLoc(a), genTypeInfo(p.module, t)]), a.storage)
|
addrLoc(a), genTypeInfo(p.module, t, e.info)]), a.storage)
|
||||||
of tyOpenArray, tyVarargs:
|
of tyOpenArray, tyVarargs:
|
||||||
var b: TLoc
|
var b: TLoc
|
||||||
case a.t.kind
|
case a.t.kind
|
||||||
|
|
@ -1383,22 +1389,22 @@ proc genRepr(p: BProc, e: PNode, d: var TLoc) =
|
||||||
else: internalError(e.sons[0].info, "genRepr()")
|
else: internalError(e.sons[0].info, "genRepr()")
|
||||||
putIntoDest(p, d, e,
|
putIntoDest(p, d, e,
|
||||||
ropecg(p.module, "#reprOpenArray($1, $2)", [rdLoc(b),
|
ropecg(p.module, "#reprOpenArray($1, $2)", [rdLoc(b),
|
||||||
genTypeInfo(p.module, elemType(t))]), a.storage)
|
genTypeInfo(p.module, elemType(t), e.info)]), a.storage)
|
||||||
of tyCString, tyArray, tyRef, tyPtr, tyPointer, tyNil, tySequence:
|
of tyCString, tyArray, tyRef, tyPtr, tyPointer, tyNil, tySequence:
|
||||||
putIntoDest(p, d, e,
|
putIntoDest(p, d, e,
|
||||||
ropecg(p.module, "#reprAny($1, $2)", [
|
ropecg(p.module, "#reprAny($1, $2)", [
|
||||||
rdLoc(a), genTypeInfo(p.module, t)]), a.storage)
|
rdLoc(a), genTypeInfo(p.module, t, e.info)]), a.storage)
|
||||||
of tyEmpty, tyVoid:
|
of tyEmpty, tyVoid:
|
||||||
localError(e.info, "'repr' doesn't support 'void' type")
|
localError(e.info, "'repr' doesn't support 'void' type")
|
||||||
else:
|
else:
|
||||||
putIntoDest(p, d, e, ropecg(p.module, "#reprAny($1, $2)",
|
putIntoDest(p, d, e, ropecg(p.module, "#reprAny($1, $2)",
|
||||||
[addrLoc(a), genTypeInfo(p.module, t)]),
|
[addrLoc(a), genTypeInfo(p.module, t, e.info)]),
|
||||||
a.storage)
|
a.storage)
|
||||||
gcUsage(e)
|
gcUsage(e)
|
||||||
|
|
||||||
proc genGetTypeInfo(p: BProc, e: PNode, d: var TLoc) =
|
proc genGetTypeInfo(p: BProc, e: PNode, d: var TLoc) =
|
||||||
let t = e.sons[1].typ
|
let t = e.sons[1].typ
|
||||||
putIntoDest(p, d, e, genTypeInfo(p.module, t))
|
putIntoDest(p, d, e, genTypeInfo(p.module, t, e.info))
|
||||||
|
|
||||||
proc genDollar(p: BProc, n: PNode, d: var TLoc, frmt: string) =
|
proc genDollar(p: BProc, n: PNode, d: var TLoc, frmt: string) =
|
||||||
var a: TLoc
|
var a: TLoc
|
||||||
|
|
@ -1980,10 +1986,10 @@ proc upConv(p: BProc, n: PNode, d: var TLoc) =
|
||||||
t = skipTypes(t.sons[0], skipPtrs)
|
t = skipTypes(t.sons[0], skipPtrs)
|
||||||
if nilCheck != nil:
|
if nilCheck != nil:
|
||||||
linefmt(p, cpsStmts, "if ($1) #chckObj($2.m_type, $3);$n",
|
linefmt(p, cpsStmts, "if ($1) #chckObj($2.m_type, $3);$n",
|
||||||
nilCheck, r, genTypeInfo(p.module, dest))
|
nilCheck, r, genTypeInfo(p.module, dest, n.info))
|
||||||
else:
|
else:
|
||||||
linefmt(p, cpsStmts, "#chckObj($1.m_type, $2);$n",
|
linefmt(p, cpsStmts, "#chckObj($1.m_type, $2);$n",
|
||||||
r, genTypeInfo(p.module, dest))
|
r, genTypeInfo(p.module, dest, n.info))
|
||||||
if n.sons[0].typ.kind != tyObject:
|
if n.sons[0].typ.kind != tyObject:
|
||||||
putIntoDest(p, d, n,
|
putIntoDest(p, d, n,
|
||||||
"(($1) ($2))" % [getTypeDesc(p.module, n.typ), rdLoc(a)], a.storage)
|
"(($1) ($2))" % [getTypeDesc(p.module, n.typ), rdLoc(a)], a.storage)
|
||||||
|
|
@ -2266,7 +2272,7 @@ proc getDefaultValue(p: BProc; typ: PType; info: TLineInfo): Rope =
|
||||||
result = rope"{NIM_NIL, NIM_NIL}"
|
result = rope"{NIM_NIL, NIM_NIL}"
|
||||||
of tyObject:
|
of tyObject:
|
||||||
if not isObjLackingTypeField(t) and not p.module.compileToCpp:
|
if not isObjLackingTypeField(t) and not p.module.compileToCpp:
|
||||||
result = "{{$1}}" % [genTypeInfo(p.module, t)]
|
result = "{{$1}}" % [genTypeInfo(p.module, t, info)]
|
||||||
else:
|
else:
|
||||||
result = rope"{}"
|
result = rope"{}"
|
||||||
of tyArray, tyTuple: result = rope"{}"
|
of tyArray, tyTuple: result = rope"{}"
|
||||||
|
|
@ -2311,7 +2317,7 @@ proc getNullValueAuxT(p: BProc; orig, t: PType; obj, cons: PNode, result: var Ro
|
||||||
base = skipTypes(base, skipPtrs)
|
base = skipTypes(base, skipPtrs)
|
||||||
getNullValueAuxT(p, orig, base, base.n, cons, result, count)
|
getNullValueAuxT(p, orig, base, base.n, cons, result, count)
|
||||||
elif not isObjLackingTypeField(t) and not p.module.compileToCpp:
|
elif not isObjLackingTypeField(t) and not p.module.compileToCpp:
|
||||||
addf(result, "$1", [genTypeInfo(p.module, orig)])
|
addf(result, "$1", [genTypeInfo(p.module, orig, obj.info)])
|
||||||
inc count
|
inc count
|
||||||
getNullValueAux(p, t, obj, cons, result, count)
|
getNullValueAux(p, t, obj, cons, result, count)
|
||||||
# do not emit '{}' as that is not valid C:
|
# do not emit '{}' as that is not valid C:
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ proc registerGcRoot(p: BProc, v: PSym) =
|
||||||
containsGarbageCollectedRef(v.loc.t):
|
containsGarbageCollectedRef(v.loc.t):
|
||||||
# we register a specialized marked proc here; this has the advantage
|
# we register a specialized marked proc here; this has the advantage
|
||||||
# that it works out of the box for thread local storage then :-)
|
# that it works out of the box for thread local storage then :-)
|
||||||
let prc = genTraverseProcForGlobal(p.module, v)
|
let prc = genTraverseProcForGlobal(p.module, v, v.info)
|
||||||
appcg(p.module, p.module.initProc.procSec(cpsInit),
|
appcg(p.module, p.module.initProc.procSec(cpsInit),
|
||||||
"#nimRegisterGlobalMarker($1);$n", [prc])
|
"#nimRegisterGlobalMarker($1);$n", [prc])
|
||||||
|
|
||||||
|
|
@ -835,7 +835,7 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
|
||||||
if orExpr != nil: add(orExpr, "||")
|
if orExpr != nil: add(orExpr, "||")
|
||||||
appcg(p.module, orExpr,
|
appcg(p.module, orExpr,
|
||||||
"#isObj($1.exp->m_type, $2)",
|
"#isObj($1.exp->m_type, $2)",
|
||||||
[exc, genTypeInfo(p.module, t.sons[i].sons[j].typ)])
|
[exc, genTypeInfo(p.module, t[i][j].typ, t[i][j].info)])
|
||||||
lineF(p, cpsStmts, "if ($1) ", [orExpr])
|
lineF(p, cpsStmts, "if ($1) ", [orExpr])
|
||||||
startBlock(p)
|
startBlock(p)
|
||||||
expr(p, t.sons[i].sons[blen-1], d)
|
expr(p, t.sons[i].sons[blen-1], d)
|
||||||
|
|
@ -944,7 +944,7 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) =
|
||||||
"#isObj(#getCurrentException()->Sup.m_type, $1)"
|
"#isObj(#getCurrentException()->Sup.m_type, $1)"
|
||||||
else: "#isObj(#getCurrentException()->m_type, $1)"
|
else: "#isObj(#getCurrentException()->m_type, $1)"
|
||||||
appcg(p.module, orExpr, isObjFormat,
|
appcg(p.module, orExpr, isObjFormat,
|
||||||
[genTypeInfo(p.module, t.sons[i].sons[j].typ)])
|
[genTypeInfo(p.module, t[i][j].typ, t[i][j].info)])
|
||||||
if i > 1: line(p, cpsStmts, "else ")
|
if i > 1: line(p, cpsStmts, "else ")
|
||||||
startBlock(p, "if ($1) {$n", [orExpr])
|
startBlock(p, "if ($1) {$n", [orExpr])
|
||||||
linefmt(p, cpsStmts, "$1.status = 0;$n", safePoint)
|
linefmt(p, cpsStmts, "$1.status = 0;$n", safePoint)
|
||||||
|
|
@ -1062,7 +1062,7 @@ proc genWatchpoint(p: BProc, n: PNode) =
|
||||||
let typ = skipTypes(n.sons[1].typ, abstractVarRange)
|
let typ = skipTypes(n.sons[1].typ, abstractVarRange)
|
||||||
lineCg(p, cpsStmts, "#dbgRegisterWatchpoint($1, (NCSTRING)$2, $3);$n",
|
lineCg(p, cpsStmts, "#dbgRegisterWatchpoint($1, (NCSTRING)$2, $3);$n",
|
||||||
[a.addrLoc, makeCString(renderTree(n.sons[1])),
|
[a.addrLoc, makeCString(renderTree(n.sons[1])),
|
||||||
genTypeInfo(p.module, typ)])
|
genTypeInfo(p.module, typ, n.info)])
|
||||||
|
|
||||||
proc genPragma(p: BProc, n: PNode) =
|
proc genPragma(p: BProc, n: PNode) =
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
|
|
@ -1092,7 +1092,7 @@ proc genDiscriminantCheck(p: BProc, a, tmp: TLoc, objtype: PType,
|
||||||
field: PSym) =
|
field: PSym) =
|
||||||
var t = skipTypes(objtype, abstractVar)
|
var t = skipTypes(objtype, abstractVar)
|
||||||
assert t.kind == tyObject
|
assert t.kind == tyObject
|
||||||
discard genTypeInfo(p.module, t)
|
discard genTypeInfo(p.module, t, a.lode.info)
|
||||||
var L = lengthOrd(field.typ)
|
var L = lengthOrd(field.typ)
|
||||||
if not containsOrIncl(p.module.declaredThings, field.id):
|
if not containsOrIncl(p.module.declaredThings, field.id):
|
||||||
appcg(p.module, cfsVars, "extern $1",
|
appcg(p.module, cfsVars, "extern $1",
|
||||||
|
|
|
||||||
|
|
@ -151,8 +151,8 @@ proc genTraverseProc(m: BModule, origTyp: PType; sig: SigHash;
|
||||||
m.s[cfsProcHeaders].addf("$1;$n", [header])
|
m.s[cfsProcHeaders].addf("$1;$n", [header])
|
||||||
m.s[cfsProcs].add(generatedProc)
|
m.s[cfsProcs].add(generatedProc)
|
||||||
|
|
||||||
proc genTraverseProcForGlobal(m: BModule, s: PSym): Rope =
|
proc genTraverseProcForGlobal(m: BModule, s: PSym; info: TLineInfo): Rope =
|
||||||
discard genTypeInfo(m, s.loc.t)
|
discard genTypeInfo(m, s.loc.t, info)
|
||||||
|
|
||||||
var c: TTraversalClosure
|
var c: TTraversalClosure
|
||||||
var p = newProc(nil, m)
|
var p = newProc(nil, m)
|
||||||
|
|
|
||||||
|
|
@ -278,7 +278,10 @@ proc ccgIntroducedPtr(s: PSym): bool =
|
||||||
elif tfByCopy in pt.flags: return false
|
elif tfByCopy in pt.flags: return false
|
||||||
case pt.kind
|
case pt.kind
|
||||||
of tyObject:
|
of tyObject:
|
||||||
if (optByRef in s.options) or (getSize(pt) > platform.floatSize * 3):
|
if s.typ.sym != nil and sfForward in s.typ.sym.flags:
|
||||||
|
# forwarded objects are *always* passed by pointers for consistency!
|
||||||
|
result = true
|
||||||
|
elif (optByRef in s.options) or (getSize(pt) > platform.floatSize * 3):
|
||||||
result = true # requested anyway
|
result = true # requested anyway
|
||||||
elif (tfFinal in pt.flags) and (pt.sons[0] == nil):
|
elif (tfFinal in pt.flags) and (pt.sons[0] == nil):
|
||||||
result = false # no need, because no subtyping possible
|
result = false # no need, because no subtyping possible
|
||||||
|
|
@ -854,11 +857,12 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope =
|
||||||
[structOrUnion(t), result])
|
[structOrUnion(t), result])
|
||||||
assert m.forwTypeCache[sig] == result
|
assert m.forwTypeCache[sig] == result
|
||||||
m.typeCache[sig] = result # always call for sideeffects:
|
m.typeCache[sig] = result # always call for sideeffects:
|
||||||
let recdesc = if t.kind != tyTuple: getRecordDesc(m, t, result, check)
|
if not incompleteType(t):
|
||||||
else: getTupleDesc(m, t, result, check)
|
let recdesc = if t.kind != tyTuple: getRecordDesc(m, t, result, check)
|
||||||
if not isImportedType(t):
|
else: getTupleDesc(m, t, result, check)
|
||||||
add(m.s[cfsTypes], recdesc)
|
if not isImportedType(t):
|
||||||
elif tfIncompleteStruct notin t.flags: addAbiCheck(m, t, result)
|
add(m.s[cfsTypes], recdesc)
|
||||||
|
elif tfIncompleteStruct notin t.flags: addAbiCheck(m, t, result)
|
||||||
of tySet:
|
of tySet:
|
||||||
result = $t.kind & '_' & getTypeName(m, t.lastSon, hashType t.lastSon)
|
result = $t.kind & '_' & getTypeName(m, t.lastSon, hashType t.lastSon)
|
||||||
m.typeCache[sig] = result
|
m.typeCache[sig] = result
|
||||||
|
|
@ -935,12 +939,13 @@ proc genProcHeader(m: BModule, prc: PSym): Rope =
|
||||||
|
|
||||||
# ------------------ type info generation -------------------------------------
|
# ------------------ type info generation -------------------------------------
|
||||||
|
|
||||||
proc genTypeInfo(m: BModule, t: PType): Rope
|
proc genTypeInfo(m: BModule, t: PType; info: TLineInfo): Rope
|
||||||
proc getNimNode(m: BModule): Rope =
|
proc getNimNode(m: BModule): Rope =
|
||||||
result = "$1[$2]" % [m.typeNodesName, rope(m.typeNodes)]
|
result = "$1[$2]" % [m.typeNodesName, rope(m.typeNodes)]
|
||||||
inc(m.typeNodes)
|
inc(m.typeNodes)
|
||||||
|
|
||||||
proc genTypeInfoAuxBase(m: BModule; typ, origType: PType; name, base: Rope) =
|
proc genTypeInfoAuxBase(m: BModule; typ, origType: PType;
|
||||||
|
name, base: Rope; info: TLineInfo) =
|
||||||
var nimtypeKind: int
|
var nimtypeKind: int
|
||||||
#allocMemTI(m, typ, name)
|
#allocMemTI(m, typ, name)
|
||||||
if isObjLackingTypeField(typ):
|
if isObjLackingTypeField(typ):
|
||||||
|
|
@ -970,15 +975,16 @@ proc genTypeInfoAuxBase(m: BModule; typ, origType: PType; name, base: Rope) =
|
||||||
[name])
|
[name])
|
||||||
addf(m.s[cfsVars], "TNimType $1;$n", [name])
|
addf(m.s[cfsVars], "TNimType $1;$n", [name])
|
||||||
|
|
||||||
proc genTypeInfoAux(m: BModule, typ, origType: PType, name: Rope) =
|
proc genTypeInfoAux(m: BModule, typ, origType: PType, name: Rope;
|
||||||
|
info: TLineInfo) =
|
||||||
var base: Rope
|
var base: Rope
|
||||||
if sonsLen(typ) > 0 and typ.lastSon != nil:
|
if sonsLen(typ) > 0 and typ.lastSon != nil:
|
||||||
var x = typ.lastSon
|
var x = typ.lastSon
|
||||||
if typ.kind == tyObject: x = x.skipTypes(skipPtrs)
|
if typ.kind == tyObject: x = x.skipTypes(skipPtrs)
|
||||||
base = genTypeInfo(m, x)
|
base = genTypeInfo(m, x, info)
|
||||||
else:
|
else:
|
||||||
base = rope("0")
|
base = rope("0")
|
||||||
genTypeInfoAuxBase(m, typ, origType, name, base)
|
genTypeInfoAuxBase(m, typ, origType, name, base, info)
|
||||||
|
|
||||||
proc discriminatorTableName(m: BModule, objtype: PType, d: PSym): Rope =
|
proc discriminatorTableName(m: BModule, objtype: PType, d: PSym): Rope =
|
||||||
# bugfix: we need to search the type that contains the discriminator:
|
# bugfix: we need to search the type that contains the discriminator:
|
||||||
|
|
@ -994,19 +1000,20 @@ proc discriminatorTableDecl(m: BModule, objtype: PType, d: PSym): Rope =
|
||||||
var tmp = discriminatorTableName(m, objtype, d)
|
var tmp = discriminatorTableName(m, objtype, d)
|
||||||
result = "TNimNode* $1[$2];$n" % [tmp, rope(lengthOrd(d.typ)+1)]
|
result = "TNimNode* $1[$2];$n" % [tmp, rope(lengthOrd(d.typ)+1)]
|
||||||
|
|
||||||
proc genObjectFields(m: BModule, typ, origType: PType, n: PNode, expr: Rope) =
|
proc genObjectFields(m: BModule, typ, origType: PType, n: PNode, expr: Rope;
|
||||||
|
info: TLineInfo) =
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkRecList:
|
of nkRecList:
|
||||||
var L = sonsLen(n)
|
var L = sonsLen(n)
|
||||||
if L == 1:
|
if L == 1:
|
||||||
genObjectFields(m, typ, origType, n.sons[0], expr)
|
genObjectFields(m, typ, origType, n.sons[0], expr, info)
|
||||||
elif L > 0:
|
elif L > 0:
|
||||||
var tmp = getTempName(m)
|
var tmp = getTempName(m)
|
||||||
addf(m.s[cfsTypeInit1], "static TNimNode* $1[$2];$n", [tmp, rope(L)])
|
addf(m.s[cfsTypeInit1], "static TNimNode* $1[$2];$n", [tmp, rope(L)])
|
||||||
for i in countup(0, L-1):
|
for i in countup(0, L-1):
|
||||||
var tmp2 = getNimNode(m)
|
var tmp2 = getNimNode(m)
|
||||||
addf(m.s[cfsTypeInit3], "$1[$2] = &$3;$n", [tmp, rope(i), tmp2])
|
addf(m.s[cfsTypeInit3], "$1[$2] = &$3;$n", [tmp, rope(i), tmp2])
|
||||||
genObjectFields(m, typ, origType, n.sons[i], tmp2)
|
genObjectFields(m, typ, origType, n.sons[i], tmp2, info)
|
||||||
addf(m.s[cfsTypeInit3], "$1.len = $2; $1.kind = 2; $1.sons = &$3[0];$n",
|
addf(m.s[cfsTypeInit3], "$1.len = $2; $1.kind = 2; $1.sons = &$3[0];$n",
|
||||||
[expr, rope(L), tmp])
|
[expr, rope(L), tmp])
|
||||||
else:
|
else:
|
||||||
|
|
@ -1024,14 +1031,14 @@ proc genObjectFields(m: BModule, typ, origType: PType, n: PNode, expr: Rope) =
|
||||||
"$1.offset = offsetof($2, $3);$n" & "$1.typ = $4;$n" &
|
"$1.offset = offsetof($2, $3);$n" & "$1.typ = $4;$n" &
|
||||||
"$1.name = $5;$n" & "$1.sons = &$6[0];$n" &
|
"$1.name = $5;$n" & "$1.sons = &$6[0];$n" &
|
||||||
"$1.len = $7;$n", [expr, getTypeDesc(m, origType), field.loc.r,
|
"$1.len = $7;$n", [expr, getTypeDesc(m, origType), field.loc.r,
|
||||||
genTypeInfo(m, field.typ),
|
genTypeInfo(m, field.typ, info),
|
||||||
makeCString(field.name.s),
|
makeCString(field.name.s),
|
||||||
tmp, rope(L)])
|
tmp, rope(L)])
|
||||||
addf(m.s[cfsData], "TNimNode* $1[$2];$n", [tmp, rope(L+1)])
|
addf(m.s[cfsData], "TNimNode* $1[$2];$n", [tmp, rope(L+1)])
|
||||||
for i in countup(1, sonsLen(n)-1):
|
for i in countup(1, sonsLen(n)-1):
|
||||||
var b = n.sons[i] # branch
|
var b = n.sons[i] # branch
|
||||||
var tmp2 = getNimNode(m)
|
var tmp2 = getNimNode(m)
|
||||||
genObjectFields(m, typ, origType, lastSon(b), tmp2)
|
genObjectFields(m, typ, origType, lastSon(b), tmp2, info)
|
||||||
case b.kind
|
case b.kind
|
||||||
of nkOfBranch:
|
of nkOfBranch:
|
||||||
if sonsLen(b) < 2:
|
if sonsLen(b) < 2:
|
||||||
|
|
@ -1059,15 +1066,20 @@ proc genObjectFields(m: BModule, typ, origType: PType, n: PNode, expr: Rope) =
|
||||||
addf(m.s[cfsTypeInit3], "$1.kind = 1;$n" &
|
addf(m.s[cfsTypeInit3], "$1.kind = 1;$n" &
|
||||||
"$1.offset = offsetof($2, $3);$n" & "$1.typ = $4;$n" &
|
"$1.offset = offsetof($2, $3);$n" & "$1.typ = $4;$n" &
|
||||||
"$1.name = $5;$n", [expr, getTypeDesc(m, origType),
|
"$1.name = $5;$n", [expr, getTypeDesc(m, origType),
|
||||||
field.loc.r, genTypeInfo(m, field.typ), makeCString(field.name.s)])
|
field.loc.r, genTypeInfo(m, field.typ, info), makeCString(field.name.s)])
|
||||||
else: internalError(n.info, "genObjectFields")
|
else: internalError(n.info, "genObjectFields")
|
||||||
|
|
||||||
proc genObjectInfo(m: BModule, typ, origType: PType, name: Rope) =
|
proc genObjectInfo(m: BModule, typ, origType: PType, name: Rope; info: TLineInfo) =
|
||||||
if typ.kind == tyObject: genTypeInfoAux(m, typ, origType, name)
|
if typ.kind == tyObject:
|
||||||
else: genTypeInfoAuxBase(m, typ, origType, name, rope("0"))
|
if incompleteType(typ):
|
||||||
|
localError(info, "request for RTTI generation for incomplete object: " &
|
||||||
|
typeToString(typ))
|
||||||
|
genTypeInfoAux(m, typ, origType, name, info)
|
||||||
|
else:
|
||||||
|
genTypeInfoAuxBase(m, typ, origType, name, rope("0"), info)
|
||||||
var tmp = getNimNode(m)
|
var tmp = getNimNode(m)
|
||||||
if not isImportedType(typ):
|
if not isImportedType(typ):
|
||||||
genObjectFields(m, typ, origType, typ.n, tmp)
|
genObjectFields(m, typ, origType, typ.n, tmp, info)
|
||||||
addf(m.s[cfsTypeInit3], "$1.node = &$2;$n", [name, tmp])
|
addf(m.s[cfsTypeInit3], "$1.node = &$2;$n", [name, tmp])
|
||||||
var t = typ.sons[0]
|
var t = typ.sons[0]
|
||||||
while t != nil:
|
while t != nil:
|
||||||
|
|
@ -1075,8 +1087,8 @@ proc genObjectInfo(m: BModule, typ, origType: PType, name: Rope) =
|
||||||
t.flags.incl tfObjHasKids
|
t.flags.incl tfObjHasKids
|
||||||
t = t.sons[0]
|
t = t.sons[0]
|
||||||
|
|
||||||
proc genTupleInfo(m: BModule, typ, origType: PType, name: Rope) =
|
proc genTupleInfo(m: BModule, typ, origType: PType, name: Rope; info: TLineInfo) =
|
||||||
genTypeInfoAuxBase(m, typ, typ, name, rope("0"))
|
genTypeInfoAuxBase(m, typ, typ, name, rope("0"), info)
|
||||||
var expr = getNimNode(m)
|
var expr = getNimNode(m)
|
||||||
var length = sonsLen(typ)
|
var length = sonsLen(typ)
|
||||||
if length > 0:
|
if length > 0:
|
||||||
|
|
@ -1090,7 +1102,7 @@ proc genTupleInfo(m: BModule, typ, origType: PType, name: Rope) =
|
||||||
"$1.offset = offsetof($2, Field$3);$n" &
|
"$1.offset = offsetof($2, Field$3);$n" &
|
||||||
"$1.typ = $4;$n" &
|
"$1.typ = $4;$n" &
|
||||||
"$1.name = \"Field$3\";$n",
|
"$1.name = \"Field$3\";$n",
|
||||||
[tmp2, getTypeDesc(m, origType), rope(i), genTypeInfo(m, a)])
|
[tmp2, getTypeDesc(m, origType), rope(i), genTypeInfo(m, a, info)])
|
||||||
addf(m.s[cfsTypeInit3], "$1.len = $2; $1.kind = 2; $1.sons = &$3[0];$n",
|
addf(m.s[cfsTypeInit3], "$1.len = $2; $1.kind = 2; $1.sons = &$3[0];$n",
|
||||||
[expr, rope(length), tmp])
|
[expr, rope(length), tmp])
|
||||||
else:
|
else:
|
||||||
|
|
@ -1098,12 +1110,12 @@ proc genTupleInfo(m: BModule, typ, origType: PType, name: Rope) =
|
||||||
[expr, rope(length)])
|
[expr, rope(length)])
|
||||||
addf(m.s[cfsTypeInit3], "$1.node = &$2;$n", [name, expr])
|
addf(m.s[cfsTypeInit3], "$1.node = &$2;$n", [name, expr])
|
||||||
|
|
||||||
proc genEnumInfo(m: BModule, typ: PType, name: Rope) =
|
proc genEnumInfo(m: BModule, typ: PType, name: Rope; info: TLineInfo) =
|
||||||
# Type information for enumerations is quite heavy, so we do some
|
# Type information for enumerations is quite heavy, so we do some
|
||||||
# optimizations here: The ``typ`` field is never set, as it is redundant
|
# optimizations here: The ``typ`` field is never set, as it is redundant
|
||||||
# anyway. We generate a cstring array and a loop over it. Exceptional
|
# anyway. We generate a cstring array and a loop over it. Exceptional
|
||||||
# positions will be reset after the loop.
|
# positions will be reset after the loop.
|
||||||
genTypeInfoAux(m, typ, typ, name)
|
genTypeInfoAux(m, typ, typ, name, info)
|
||||||
var nodePtrs = getTempName(m)
|
var nodePtrs = getTempName(m)
|
||||||
var length = sonsLen(typ.n)
|
var length = sonsLen(typ.n)
|
||||||
addf(m.s[cfsTypeInit1], "static TNimNode* $1[$2];$n",
|
addf(m.s[cfsTypeInit1], "static TNimNode* $1[$2];$n",
|
||||||
|
|
@ -1141,15 +1153,15 @@ proc genEnumInfo(m: BModule, typ: PType, name: Rope) =
|
||||||
# 1 << 2 is {ntfEnumHole}
|
# 1 << 2 is {ntfEnumHole}
|
||||||
addf(m.s[cfsTypeInit3], "$1.flags = 1<<2;$n", [name])
|
addf(m.s[cfsTypeInit3], "$1.flags = 1<<2;$n", [name])
|
||||||
|
|
||||||
proc genSetInfo(m: BModule, typ: PType, name: Rope) =
|
proc genSetInfo(m: BModule, typ: PType, name: Rope; info: TLineInfo) =
|
||||||
assert(typ.sons[0] != nil)
|
assert(typ.sons[0] != nil)
|
||||||
genTypeInfoAux(m, typ, typ, name)
|
genTypeInfoAux(m, typ, typ, name, info)
|
||||||
var tmp = getNimNode(m)
|
var tmp = getNimNode(m)
|
||||||
addf(m.s[cfsTypeInit3], "$1.len = $2; $1.kind = 0;$n" & "$3.node = &$1;$n",
|
addf(m.s[cfsTypeInit3], "$1.len = $2; $1.kind = 0;$n" & "$3.node = &$1;$n",
|
||||||
[tmp, rope(firstOrd(typ)), name])
|
[tmp, rope(firstOrd(typ)), name])
|
||||||
|
|
||||||
proc genArrayInfo(m: BModule, typ: PType, name: Rope) =
|
proc genArrayInfo(m: BModule, typ: PType, name: Rope; info: TLineInfo) =
|
||||||
genTypeInfoAuxBase(m, typ, typ, name, genTypeInfo(m, typ.sons[1]))
|
genTypeInfoAuxBase(m, typ, typ, name, genTypeInfo(m, typ.sons[1], info), info)
|
||||||
|
|
||||||
proc fakeClosureType(owner: PSym): PType =
|
proc fakeClosureType(owner: PSym): PType =
|
||||||
# we generate the same RTTI as for a tuple[pointer, ref tuple[]]
|
# we generate the same RTTI as for a tuple[pointer, ref tuple[]]
|
||||||
|
|
@ -1171,11 +1183,11 @@ proc genDeepCopyProc(m: BModule; s: PSym; result: Rope) =
|
||||||
addf(m.s[cfsTypeInit3], "$1.deepcopy =(void* (N_RAW_NIMCALL*)(void*))$2;$n",
|
addf(m.s[cfsTypeInit3], "$1.deepcopy =(void* (N_RAW_NIMCALL*)(void*))$2;$n",
|
||||||
[result, s.loc.r])
|
[result, s.loc.r])
|
||||||
|
|
||||||
proc genTypeInfo(m: BModule, t: PType): Rope =
|
proc genTypeInfo(m: BModule, t: PType; info: TLineInfo): Rope =
|
||||||
let origType = t
|
let origType = t
|
||||||
var t = skipTypes(origType, irrelevantForBackend + tyUserTypeClasses)
|
var t = skipTypes(origType, irrelevantForBackend + tyUserTypeClasses)
|
||||||
if t.kind == tyOpt:
|
if t.kind == tyOpt:
|
||||||
return genTypeInfo(m, optLowering(t))
|
return genTypeInfo(m, optLowering(t), info)
|
||||||
|
|
||||||
let sig = hashType(origType)
|
let sig = hashType(origType)
|
||||||
result = m.typeInfoMarker.getOrDefault(sig)
|
result = m.typeInfoMarker.getOrDefault(sig)
|
||||||
|
|
@ -1197,7 +1209,7 @@ proc genTypeInfo(m: BModule, t: PType): Rope =
|
||||||
let owner = t.skipTypes(typedescPtrs).owner.getModule
|
let owner = t.skipTypes(typedescPtrs).owner.getModule
|
||||||
if owner != m.module:
|
if owner != m.module:
|
||||||
# make sure the type info is created in the owner module
|
# make sure the type info is created in the owner module
|
||||||
discard genTypeInfo(m.g.modules[owner.position], origType)
|
discard genTypeInfo(m.g.modules[owner.position], origType, info)
|
||||||
# reference the type info as extern here
|
# reference the type info as extern here
|
||||||
discard cgsym(m, "TNimType")
|
discard cgsym(m, "TNimType")
|
||||||
discard cgsym(m, "TNimNode")
|
discard cgsym(m, "TNimNode")
|
||||||
|
|
@ -1208,35 +1220,35 @@ proc genTypeInfo(m: BModule, t: PType): Rope =
|
||||||
case t.kind
|
case t.kind
|
||||||
of tyEmpty, tyVoid: result = rope"0"
|
of tyEmpty, tyVoid: result = rope"0"
|
||||||
of tyPointer, tyBool, tyChar, tyCString, tyString, tyInt..tyUInt64, tyVar:
|
of tyPointer, tyBool, tyChar, tyCString, tyString, tyInt..tyUInt64, tyVar:
|
||||||
genTypeInfoAuxBase(m, t, t, result, rope"0")
|
genTypeInfoAuxBase(m, t, t, result, rope"0", info)
|
||||||
of tyStatic:
|
of tyStatic:
|
||||||
if t.n != nil: result = genTypeInfo(m, lastSon t)
|
if t.n != nil: result = genTypeInfo(m, lastSon t, info)
|
||||||
else: internalError("genTypeInfo(" & $t.kind & ')')
|
else: internalError("genTypeInfo(" & $t.kind & ')')
|
||||||
of tyUserTypeClasses:
|
of tyUserTypeClasses:
|
||||||
internalAssert t.isResolvedUserTypeClass
|
internalAssert t.isResolvedUserTypeClass
|
||||||
return genTypeInfo(m, t.lastSon)
|
return genTypeInfo(m, t.lastSon, info)
|
||||||
of tyProc:
|
of tyProc:
|
||||||
if t.callConv != ccClosure:
|
if t.callConv != ccClosure:
|
||||||
genTypeInfoAuxBase(m, t, t, result, rope"0")
|
genTypeInfoAuxBase(m, t, t, result, rope"0", info)
|
||||||
else:
|
else:
|
||||||
let x = fakeClosureType(t.owner)
|
let x = fakeClosureType(t.owner)
|
||||||
genTupleInfo(m, x, x, result)
|
genTupleInfo(m, x, x, result, info)
|
||||||
of tySequence, tyRef, tyOptAsRef:
|
of tySequence, tyRef, tyOptAsRef:
|
||||||
genTypeInfoAux(m, t, t, result)
|
genTypeInfoAux(m, t, t, result, info)
|
||||||
if gSelectedGC >= gcMarkAndSweep:
|
if gSelectedGC >= gcMarkAndSweep:
|
||||||
let markerProc = genTraverseProc(m, origType, sig, tiNew)
|
let markerProc = genTraverseProc(m, origType, sig, tiNew)
|
||||||
addf(m.s[cfsTypeInit3], "$1.marker = $2;$n", [result, markerProc])
|
addf(m.s[cfsTypeInit3], "$1.marker = $2;$n", [result, markerProc])
|
||||||
of tyPtr, tyRange: genTypeInfoAux(m, t, t, result)
|
of tyPtr, tyRange: genTypeInfoAux(m, t, t, result, info)
|
||||||
of tyArray: genArrayInfo(m, t, result)
|
of tyArray: genArrayInfo(m, t, result, info)
|
||||||
of tySet: genSetInfo(m, t, result)
|
of tySet: genSetInfo(m, t, result, info)
|
||||||
of tyEnum: genEnumInfo(m, t, result)
|
of tyEnum: genEnumInfo(m, t, result, info)
|
||||||
of tyObject: genObjectInfo(m, t, origType, result)
|
of tyObject: genObjectInfo(m, t, origType, result, info)
|
||||||
of tyTuple:
|
of tyTuple:
|
||||||
# if t.n != nil: genObjectInfo(m, t, result)
|
# if t.n != nil: genObjectInfo(m, t, result)
|
||||||
# else:
|
# else:
|
||||||
# BUGFIX: use consistently RTTI without proper field names; otherwise
|
# BUGFIX: use consistently RTTI without proper field names; otherwise
|
||||||
# results are not deterministic!
|
# results are not deterministic!
|
||||||
genTupleInfo(m, t, origType, result)
|
genTupleInfo(m, t, origType, result, info)
|
||||||
else: internalError("genTypeInfo(" & $t.kind & ')')
|
else: internalError("genTypeInfo(" & $t.kind & ')')
|
||||||
if t.deepCopy != nil:
|
if t.deepCopy != nil:
|
||||||
genDeepCopyProc(m, t.deepCopy, result)
|
genDeepCopyProc(m, t.deepCopy, result)
|
||||||
|
|
|
||||||
|
|
@ -271,11 +271,11 @@ proc genObjectInit(p: BProc, section: TCProcSection, t: PType, a: TLoc,
|
||||||
while (s.kind == tyObject) and (s.sons[0] != nil):
|
while (s.kind == tyObject) and (s.sons[0] != nil):
|
||||||
add(r, ".Sup")
|
add(r, ".Sup")
|
||||||
s = skipTypes(s.sons[0], skipPtrs)
|
s = skipTypes(s.sons[0], skipPtrs)
|
||||||
linefmt(p, section, "$1.m_type = $2;$n", r, genTypeInfo(p.module, t))
|
linefmt(p, section, "$1.m_type = $2;$n", r, genTypeInfo(p.module, t, a.lode.info))
|
||||||
of frEmbedded:
|
of frEmbedded:
|
||||||
# worst case for performance:
|
# worst case for performance:
|
||||||
var r = if takeAddr: addrLoc(a) else: rdLoc(a)
|
var r = if takeAddr: addrLoc(a) else: rdLoc(a)
|
||||||
linefmt(p, section, "#objectInit($1, $2);$n", r, genTypeInfo(p.module, t))
|
linefmt(p, section, "#objectInit($1, $2);$n", r, genTypeInfo(p.module, t, a.lode.info))
|
||||||
|
|
||||||
type
|
type
|
||||||
TAssignmentFlag = enum
|
TAssignmentFlag = enum
|
||||||
|
|
@ -306,7 +306,7 @@ proc resetLoc(p: BProc, loc: var TLoc) =
|
||||||
linefmt(p, cpsStmts, "#chckNil((void*)$1);$n", addrLoc(loc))
|
linefmt(p, cpsStmts, "#chckNil((void*)$1);$n", addrLoc(loc))
|
||||||
if loc.storage != OnStack:
|
if loc.storage != OnStack:
|
||||||
linefmt(p, cpsStmts, "#genericReset((void*)$1, $2);$n",
|
linefmt(p, cpsStmts, "#genericReset((void*)$1, $2);$n",
|
||||||
addrLoc(loc), genTypeInfo(p.module, loc.t))
|
addrLoc(loc), genTypeInfo(p.module, loc.t, loc.lode.info))
|
||||||
# XXX: generated reset procs should not touch the m_type
|
# XXX: generated reset procs should not touch the m_type
|
||||||
# field, so disabling this should be safe:
|
# field, so disabling this should be safe:
|
||||||
genObjectInit(p, cpsStmts, loc.t, loc, true)
|
genObjectInit(p, cpsStmts, loc.t, loc, true)
|
||||||
|
|
@ -381,7 +381,7 @@ proc localDebugInfo(p: BProc, s: PSym) =
|
||||||
lineF(p, cpsInit,
|
lineF(p, cpsInit,
|
||||||
"FR_.s[$1].address = (void*)$3; FR_.s[$1].typ = $4; FR_.s[$1].name = $2;$n",
|
"FR_.s[$1].address = (void*)$3; FR_.s[$1].typ = $4; FR_.s[$1].name = $2;$n",
|
||||||
[p.maxFrameLen.rope, makeCString(normalize(s.name.s)), a,
|
[p.maxFrameLen.rope, makeCString(normalize(s.name.s)), a,
|
||||||
genTypeInfo(p.module, s.loc.t)])
|
genTypeInfo(p.module, s.loc.t, s.info)])
|
||||||
inc(p.maxFrameLen)
|
inc(p.maxFrameLen)
|
||||||
inc p.blocks[p.blocks.len-1].frameLen
|
inc p.blocks[p.blocks.len-1].frameLen
|
||||||
|
|
||||||
|
|
@ -451,7 +451,7 @@ proc assignGlobalVar(p: BProc, n: PNode) =
|
||||||
appcg(p.module, p.module.s[cfsDebugInit],
|
appcg(p.module, p.module.s[cfsDebugInit],
|
||||||
"#dbgRegisterGlobal($1, &$2, $3);$n",
|
"#dbgRegisterGlobal($1, &$2, $3);$n",
|
||||||
[makeCString(normalize(s.owner.name.s & '.' & s.name.s)),
|
[makeCString(normalize(s.owner.name.s & '.' & s.name.s)),
|
||||||
s.loc.r, genTypeInfo(p.module, s.typ)])
|
s.loc.r, genTypeInfo(p.module, s.typ, n.info)])
|
||||||
|
|
||||||
proc assignParam(p: BProc, s: PSym) =
|
proc assignParam(p: BProc, s: PSym) =
|
||||||
assert(s.loc.r != nil)
|
assert(s.loc.r != nil)
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ const
|
||||||
wPure, wHeader, wCompilerproc, wFinal, wSize, wExtern, wShallow,
|
wPure, wHeader, wCompilerproc, wFinal, wSize, wExtern, wShallow,
|
||||||
wImportCpp, wImportObjC, wError, wIncompleteStruct, wByCopy, wByRef,
|
wImportCpp, wImportObjC, wError, wIncompleteStruct, wByCopy, wByRef,
|
||||||
wInheritable, wGensym, wInject, wRequiresInit, wUnchecked, wUnion, wPacked,
|
wInheritable, wGensym, wInject, wRequiresInit, wUnchecked, wUnion, wPacked,
|
||||||
wBorrow, wGcSafe, wExportNims, wPartial, wUsed, wExplain}
|
wBorrow, wGcSafe, wExportNims, wPartial, wUsed, wExplain, wForward}
|
||||||
fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern,
|
fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern,
|
||||||
wImportCpp, wImportObjC, wError, wGuard, wBitsize, wUsed}
|
wImportCpp, wImportObjC, wError, wGuard, wBitsize, wUsed}
|
||||||
varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl,
|
varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl,
|
||||||
|
|
@ -799,6 +799,10 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
|
||||||
noVal(it)
|
noVal(it)
|
||||||
if sym.typ == nil or tfFinal in sym.typ.flags: invalidPragma(it)
|
if sym.typ == nil or tfFinal in sym.typ.flags: invalidPragma(it)
|
||||||
else: incl(sym.typ.flags, tfInheritable)
|
else: incl(sym.typ.flags, tfInheritable)
|
||||||
|
of wForward:
|
||||||
|
noVal(it)
|
||||||
|
if sym.typ == nil: invalidPragma(it)
|
||||||
|
else: incl(sym.flags, sfForward)
|
||||||
of wAcyclic:
|
of wAcyclic:
|
||||||
noVal(it)
|
noVal(it)
|
||||||
if sym.typ == nil: invalidPragma(it)
|
if sym.typ == nil: invalidPragma(it)
|
||||||
|
|
|
||||||
|
|
@ -787,6 +787,7 @@ proc typeSectionLeftSidePass(c: PContext, n: PNode) =
|
||||||
s.typ.sym = s # process pragmas:
|
s.typ.sym = s # process pragmas:
|
||||||
if name.kind == nkPragmaExpr:
|
if name.kind == nkPragmaExpr:
|
||||||
pragma(c, s, name.sons[1], typePragmas)
|
pragma(c, s, name.sons[1], typePragmas)
|
||||||
|
if sfForward in s.flags: strTableAdd(c.graph.forwardedTypes, s)
|
||||||
# add it here, so that recursive types are possible:
|
# add it here, so that recursive types are possible:
|
||||||
if sfGenSym notin s.flags: addInterfaceDecl(c, s)
|
if sfGenSym notin s.flags: addInterfaceDecl(c, s)
|
||||||
a.sons[0] = newSymNode(s)
|
a.sons[0] = newSymNode(s)
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ type
|
||||||
wFloatchecks, wNanChecks, wInfChecks,
|
wFloatchecks, wNanChecks, wInfChecks,
|
||||||
wAssertions, wPatterns, wWarnings,
|
wAssertions, wPatterns, wWarnings,
|
||||||
wHints, wOptimization, wRaises, wWrites, wReads, wSize, wEffects, wTags,
|
wHints, wOptimization, wRaises, wWrites, wReads, wSize, wEffects, wTags,
|
||||||
wDeadCodeElim, wSafecode, wNoForward, wReorder, wNoRewrite,
|
wDeadCodeElim, wSafecode, wForward, wNoForward, wReorder, wNoRewrite,
|
||||||
wPragma,
|
wPragma,
|
||||||
wCompileTime, wNoInit,
|
wCompileTime, wNoInit,
|
||||||
wPassc, wPassl, wBorrow, wDiscardable,
|
wPassc, wPassl, wBorrow, wDiscardable,
|
||||||
|
|
@ -143,7 +143,7 @@ const
|
||||||
|
|
||||||
"assertions", "patterns", "warnings", "hints",
|
"assertions", "patterns", "warnings", "hints",
|
||||||
"optimization", "raises", "writes", "reads", "size", "effects", "tags",
|
"optimization", "raises", "writes", "reads", "size", "effects", "tags",
|
||||||
"deadcodeelim", "safecode", "noforward", "reorder", "norewrite",
|
"deadcodeelim", "safecode", "forward", "noforward", "reorder", "norewrite",
|
||||||
"pragma",
|
"pragma",
|
||||||
"compiletime", "noinit",
|
"compiletime", "noinit",
|
||||||
"passc", "passl", "borrow", "discardable", "fieldchecks",
|
"passc", "passl", "borrow", "discardable", "fieldchecks",
|
||||||
|
|
|
||||||
10
todo.txt
10
todo.txt
|
|
@ -1,11 +1,11 @@
|
||||||
version 1.0 battle plan
|
version 1.0 battle plan
|
||||||
=======================
|
=======================
|
||||||
|
|
||||||
- make 'not nil' the default (produce warnings instead of errors for
|
|
||||||
a smooth migration path)
|
|
||||||
- case objects needs to be safe and need to support pattern matching
|
|
||||||
- implement a way to forward object type declarations across module
|
- implement a way to forward object type declarations across module
|
||||||
boundaries; C++ style
|
boundaries; C++ style
|
||||||
|
- deprecate unary '<'
|
||||||
|
- remove 'mod x' type rule
|
||||||
|
- implement x[^1] differently, no compiler magic
|
||||||
- fix "high priority" bugs
|
- fix "high priority" bugs
|
||||||
- try to fix as many compiler crashes as reasonable
|
- try to fix as many compiler crashes as reasonable
|
||||||
|
|
||||||
|
|
@ -13,6 +13,10 @@ version 1.0 battle plan
|
||||||
Not critical for 1.0
|
Not critical for 1.0
|
||||||
====================
|
====================
|
||||||
|
|
||||||
|
- make 'not nil' the default (produce warnings instead of errors for
|
||||||
|
a smooth migration path)
|
||||||
|
- case objects needs to be safe and need to support pattern matching
|
||||||
|
|
||||||
- find a solution for the x.f[T](y) gotcha
|
- find a solution for the x.f[T](y) gotcha
|
||||||
- implement ``.delegate`` for .experimental
|
- implement ``.delegate`` for .experimental
|
||||||
- annotation support for getType()
|
- annotation support for getType()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue