mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 17:04:41 +00:00
* implements: [C++] constructor pragma improvement (fix #21921) t * fix test so it doesnt use echo in globals * Update compiler/ccgtypes.nim * Update lib/std/private/dragonbox.nim --------- Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
This commit is contained in:
@@ -35,7 +35,9 @@ proc isAssignedImmediately(conf: ConfigRef; n: PNode): bool {.inline.} =
|
||||
if n.kind == nkEmpty:
|
||||
result = false
|
||||
elif n.kind in nkCallKinds and n[0] != nil and n[0].typ != nil and n[0].typ.skipTypes(abstractInst).kind == tyProc:
|
||||
if isInvalidReturnType(conf, n[0].typ, true):
|
||||
if n[0].kind == nkSym and sfConstructor in n[0].sym.flags:
|
||||
result = true
|
||||
elif isInvalidReturnType(conf, n[0].typ, true):
|
||||
# var v = f()
|
||||
# is transformed into: var v; f(addr v)
|
||||
# where 'f' **does not** initialize the result!
|
||||
@@ -288,7 +290,7 @@ proc potentialValueInit(p: BProc; v: PSym; value: PNode; result: var Rope) =
|
||||
#echo "New code produced for ", v.name.s, " ", p.config $ value.info
|
||||
genBracedInit(p, value, isConst = false, v.typ, result)
|
||||
|
||||
proc genCppVarForConstructor(p: BProc, v: PSym; vn, value: PNode; decl: var Rope) =
|
||||
proc genCppVarForCtor(p: BProc, v: PSym; vn, value: PNode; decl: var Rope) =
|
||||
var params = newRopeAppender()
|
||||
var argsCounter = 0
|
||||
let typ = skipTypes(value[0].typ, abstractInst)
|
||||
@@ -307,7 +309,7 @@ proc genSingleVar(p: BProc, v: PSym; vn, value: PNode) =
|
||||
genGotoVar(p, value)
|
||||
return
|
||||
let imm = isAssignedImmediately(p.config, value)
|
||||
let isCppConstructorCall = p.module.compileToCpp and imm and
|
||||
let isCppCtorCall = p.module.compileToCpp and imm and
|
||||
value.kind in nkCallKinds and value[0].kind == nkSym and
|
||||
v.typ.kind != tyPtr and sfConstructor in value[0].sym.flags
|
||||
var targetProc = p
|
||||
@@ -321,8 +323,8 @@ proc genSingleVar(p: BProc, v: PSym; vn, value: PNode) =
|
||||
if sfPure in v.flags:
|
||||
# v.owner.kind != skModule:
|
||||
targetProc = p.module.preInitProc
|
||||
if isCppConstructorCall and not containsHiddenPointer(v.typ):
|
||||
callGlobalVarCppConstructor(targetProc, v, vn, value)
|
||||
if isCppCtorCall and not containsHiddenPointer(v.typ):
|
||||
callGlobalVarCppCtor(targetProc, v, vn, value)
|
||||
else:
|
||||
assignGlobalVar(targetProc, vn, valueAsRope)
|
||||
|
||||
@@ -356,8 +358,8 @@ proc genSingleVar(p: BProc, v: PSym; vn, value: PNode) =
|
||||
genLineDir(p, vn)
|
||||
var decl = localVarDecl(p, vn)
|
||||
var tmp: TLoc
|
||||
if isCppConstructorCall:
|
||||
genCppVarForConstructor(p, v, vn, value, decl)
|
||||
if isCppCtorCall:
|
||||
genCppVarForCtor(p, v, vn, value, decl)
|
||||
line(p, cpsStmts, decl)
|
||||
else:
|
||||
initLocExprSingleUse(p, value, tmp)
|
||||
@@ -388,7 +390,7 @@ proc genSingleVar(p: BProc, v: PSym; vn, value: PNode) =
|
||||
startBlock(targetProc)
|
||||
if value.kind != nkEmpty and valueAsRope.len == 0:
|
||||
genLineDir(targetProc, vn)
|
||||
if not isCppConstructorCall:
|
||||
if not isCppCtorCall:
|
||||
loadInto(targetProc, vn, value, v.loc)
|
||||
if forHcr:
|
||||
endBlock(targetProc)
|
||||
|
||||
@@ -11,8 +11,7 @@
|
||||
|
||||
# ------------------------- Name Mangling --------------------------------
|
||||
|
||||
import sighashes, modulegraphs
|
||||
import strscans
|
||||
import sighashes, modulegraphs, strscans
|
||||
import ../dist/checksums/src/checksums/md5
|
||||
|
||||
type
|
||||
@@ -488,30 +487,36 @@ proc multiFormat*(frmt: var string, chars : static openArray[char], args: openAr
|
||||
res.add(substr(frmt, start, i - 1))
|
||||
frmt = res
|
||||
|
||||
proc genVirtualProcParams(m: BModule; t: PType, rettype, params: var string,
|
||||
proc genMemberProcParams(m: BModule; prc: PSym, superCall, rettype, params: var string,
|
||||
check: var IntSet, declareEnvironment=true;
|
||||
weakDep=false;) =
|
||||
if t[0] == nil or isInvalidReturnType(m.config, t):
|
||||
let t = prc.typ
|
||||
let isCtor = sfConstructor in prc.flags
|
||||
if isCtor:
|
||||
rettype = ""
|
||||
elif t[0] == nil or isInvalidReturnType(m.config, t):
|
||||
rettype = "void"
|
||||
else:
|
||||
if rettype == "":
|
||||
rettype = getTypeDescAux(m, t[0], check, dkResult)
|
||||
else:
|
||||
rettype = runtimeFormat(rettype.replace("'0", "$1"), [getTypeDescAux(m, t[0], check, dkResult)])
|
||||
var this = t.n[1].sym
|
||||
fillParamName(m, this)
|
||||
fillLoc(this.loc, locParam, t.n[1],
|
||||
this.paramStorageLoc)
|
||||
if this.typ.kind == tyPtr:
|
||||
this.loc.r = "this"
|
||||
else:
|
||||
this.loc.r = "(*this)"
|
||||
|
||||
var types = @[getTypeDescWeak(m, this.typ, check, dkParam)]
|
||||
var names = @[this.loc.r]
|
||||
var types, names, args: seq[string]
|
||||
if not isCtor:
|
||||
var this = t.n[1].sym
|
||||
fillParamName(m, this)
|
||||
fillLoc(this.loc, locParam, t.n[1],
|
||||
this.paramStorageLoc)
|
||||
if this.typ.kind == tyPtr:
|
||||
this.loc.r = "this"
|
||||
else:
|
||||
this.loc.r = "(*this)"
|
||||
names.add this.loc.r
|
||||
types.add getTypeDescWeak(m, this.typ, check, dkParam)
|
||||
|
||||
for i in 2..<t.n.len:
|
||||
if t.n[i].kind != nkSym: internalError(m.config, t.n.info, "genVirtualProcParams")
|
||||
let firstParam = if isCtor: 1 else: 2
|
||||
for i in firstParam..<t.n.len:
|
||||
if t.n[i].kind != nkSym: internalError(m.config, t.n.info, "genMemberProcParams")
|
||||
var param = t.n[i].sym
|
||||
var descKind = dkParam
|
||||
if optByRef in param.options:
|
||||
@@ -534,9 +539,15 @@ proc genVirtualProcParams(m: BModule; t: PType, rettype, params: var string,
|
||||
name = param.loc.r
|
||||
types.add typ
|
||||
names.add name
|
||||
args.add types[^1] & " " & names[^1]
|
||||
|
||||
multiFormat(params, @['\'', '#'], [types, names])
|
||||
multiFormat(superCall, @['\'', '#'], [types, names])
|
||||
if params == "()":
|
||||
params = "(void)"
|
||||
if types.len == 0:
|
||||
params = "(void)"
|
||||
else:
|
||||
params = "(" & args.join(", ") & ")"
|
||||
if tfVarargs in t.flags:
|
||||
if params != "(":
|
||||
params[^1] = ','
|
||||
@@ -687,17 +698,25 @@ proc genRecordFieldsAux(m: BModule; n: PNode,
|
||||
result.addf("\t$1$3 $2;$n", [getTypeDescAux(m, field.loc.t, check, dkField), sname, noAlias])
|
||||
else: internalError(m.config, n.info, "genRecordFieldsAux()")
|
||||
|
||||
proc genVirtualProcHeader(m: BModule; prc: PSym; result: var Rope; asPtr: bool = false, isFwdDecl:bool = false)
|
||||
proc genMemberProcHeader(m: BModule; prc: PSym; result: var Rope; asPtr: bool = false, isFwdDecl:bool = false)
|
||||
|
||||
proc getRecordFields(m: BModule; typ: PType, check: var IntSet): Rope =
|
||||
result = newRopeAppender()
|
||||
genRecordFieldsAux(m, typ.n, typ, check, result)
|
||||
if typ.itemId in m.g.graph.virtualProcsPerType:
|
||||
let procs = m.g.graph.virtualProcsPerType[typ.itemId]
|
||||
if typ.itemId in m.g.graph.memberProcsPerType:
|
||||
let procs = m.g.graph.memberProcsPerType[typ.itemId]
|
||||
var isDefaultCtorGen, isCtorGen: bool
|
||||
for prc in procs:
|
||||
var header: Rope
|
||||
genVirtualProcHeader(m, prc, header, false, true)
|
||||
result.add "\t" & header & ";\n"
|
||||
if sfConstructor in prc.flags:
|
||||
isCtorGen = true
|
||||
if prc.typ.n.len == 1:
|
||||
isDefaultCtorGen = true
|
||||
genMemberProcHeader(m, prc, header, false, true)
|
||||
result.addf "$1;$n", [header]
|
||||
if isCtorGen and not isDefaultCtorGen:
|
||||
var ch: IntSet
|
||||
result.addf "$1() = default;$n", [getTypeDescAux(m, typ, ch, dkOther)]
|
||||
|
||||
proc fillObjectFields*(m: BModule; typ: PType) =
|
||||
# sometimes generic objects are not consistently merged. We patch over
|
||||
@@ -825,8 +844,6 @@ proc getOpenArrayDesc(m: BModule; t: PType, check: var IntSet; kind: TypeDescKin
|
||||
|
||||
proc getTypeDescAux(m: BModule; origTyp: PType, check: var IntSet; kind: TypeDescKind): Rope =
|
||||
# returns only the type's name
|
||||
if kind == dkRefParam:
|
||||
echo "llega con typedesc aux:", $origTyp.kind
|
||||
var t = origTyp.skipTypes(irrelevantForBackend-{tyOwned})
|
||||
if containsOrIncl(check, t.id):
|
||||
if not (isImportedCppType(origTyp) or isImportedCppType(t)):
|
||||
@@ -1106,46 +1123,63 @@ proc isReloadable(m: BModule; prc: PSym): bool =
|
||||
proc isNonReloadable(m: BModule; prc: PSym): bool =
|
||||
return m.hcrOn and sfNonReloadable in prc.flags
|
||||
|
||||
proc parseVFunctionDecl(val: string; name, params, retType: var string; isFnConst, isOverride: var bool) =
|
||||
proc parseVFunctionDecl(val: string; name, params, retType, superCall: var string; isFnConst, isOverride: var bool; isCtor: bool) =
|
||||
var afterParams: string
|
||||
if scanf(val, "$*($*)$s$*", name, params, afterParams):
|
||||
isFnConst = afterParams.find("const") > -1
|
||||
isOverride = afterParams.find("override") > -1
|
||||
discard scanf(afterParams, "->$s$* ", retType)
|
||||
if isCtor:
|
||||
discard scanf(afterParams, ":$s$*", superCall)
|
||||
else:
|
||||
discard scanf(afterParams, "->$s$* ", retType)
|
||||
|
||||
params = "(" & params & ")"
|
||||
|
||||
proc genVirtualProcHeader(m: BModule; prc: PSym; result: var Rope; asPtr: bool = false, isFwdDecl : bool = false) =
|
||||
assert sfVirtual in prc.flags
|
||||
# using static is needed for inline procs
|
||||
proc genMemberProcHeader(m: BModule; prc: PSym; result: var Rope; asPtr: bool = false, isFwdDecl : bool = false) =
|
||||
assert {sfVirtual, sfConstructor} * prc.flags != {}
|
||||
let isCtor = sfConstructor in prc.flags
|
||||
let isVirtual = not isCtor
|
||||
var check = initIntSet()
|
||||
fillBackendName(m, prc)
|
||||
fillLoc(prc.loc, locProc, prc.ast[namePos], OnUnknown)
|
||||
var typ = prc.typ.n[1].sym.typ
|
||||
var memberOp = "#."
|
||||
var memberOp = "#." #only virtual
|
||||
var typ: PType
|
||||
if isCtor:
|
||||
typ = prc.typ.sons[0]
|
||||
else:
|
||||
typ = prc.typ.sons[1]
|
||||
if typ.kind == tyPtr:
|
||||
typ = typ[0]
|
||||
memberOp = "#->"
|
||||
var typDesc = getTypeDescWeak(m, typ, check, dkParam)
|
||||
let asPtrStr = rope(if asPtr: "_PTR" else: "")
|
||||
var name, params, rettype: string
|
||||
var name, params, rettype, superCall: string
|
||||
var isFnConst, isOverride: bool
|
||||
parseVFunctionDecl(prc.constraint.strVal, name, params, rettype, isFnConst, isOverride)
|
||||
genVirtualProcParams(m, prc.typ, rettype, params, check, true, false)
|
||||
parseVFunctionDecl(prc.constraint.strVal, name, params, rettype, superCall, isFnConst, isOverride, isCtor)
|
||||
genMemberProcParams(m, prc, superCall, rettype, params, check, true, false)
|
||||
var fnConst, override: string
|
||||
if isCtor:
|
||||
name = typDesc
|
||||
if isFnConst:
|
||||
fnConst = " const"
|
||||
if isFwdDecl:
|
||||
rettype = "virtual " & rettype
|
||||
if isOverride:
|
||||
override = " override"
|
||||
else:
|
||||
prc.loc.r = "$1 $2 (@)" % [memberOp, name]
|
||||
if isVirtual:
|
||||
rettype = "virtual " & rettype
|
||||
if isOverride:
|
||||
override = " override"
|
||||
superCall = ""
|
||||
else:
|
||||
if isVirtual:
|
||||
prc.loc.r = "$1$2(@)" % [memberOp, name]
|
||||
elif superCall != "":
|
||||
superCall = " : " & superCall
|
||||
|
||||
name = "$1::$2" % [typDesc, name]
|
||||
|
||||
|
||||
result.add "N_LIB_PRIVATE "
|
||||
result.addf("$1$2($3, $4)$5$6$7",
|
||||
result.addf("$1$2($3, $4)$5$6$7$8",
|
||||
[rope(CallingConvToStr[prc.typ.callConv]), asPtrStr, rettype, name,
|
||||
params, fnConst, override])
|
||||
params, fnConst, override, superCall])
|
||||
|
||||
proc genProcHeader(m: BModule; prc: PSym; result: var Rope; asPtr: bool = false) =
|
||||
# using static is needed for inline procs
|
||||
|
||||
@@ -640,9 +640,9 @@ proc genGlobalVarDecl(p: BProc, n: PNode; td, value: Rope; decl: var Rope) =
|
||||
else:
|
||||
decl = runtimeFormat(s.cgDeclFrmt & ";$n", [td, s.loc.r])
|
||||
|
||||
proc genCppVarForConstructor(p: BProc, v: PSym; vn, value: PNode; decl: var Rope)
|
||||
proc genCppVarForCtor(p: BProc, v: PSym; vn, value: PNode; decl: var Rope)
|
||||
|
||||
proc callGlobalVarCppConstructor(p: BProc; v: PSym; vn, value: PNode) =
|
||||
proc callGlobalVarCppCtor(p: BProc; v: PSym; vn, value: PNode) =
|
||||
let s = vn.sym
|
||||
fillBackendName(p.module, s)
|
||||
fillLoc(s.loc, locGlobalVar, vn, OnHeap)
|
||||
@@ -650,7 +650,7 @@ proc callGlobalVarCppConstructor(p: BProc; v: PSym; vn, value: PNode) =
|
||||
let td = getTypeDesc(p.module, vn.sym.typ, dkVar)
|
||||
genGlobalVarDecl(p, vn, td, "", decl)
|
||||
decl.add " " & $s.loc.r
|
||||
genCppVarForConstructor(p, v, vn, value, decl)
|
||||
genCppVarForCtor(p, v, vn, value, decl)
|
||||
p.module.s[cfsVars].add decl
|
||||
|
||||
proc assignGlobalVar(p: BProc, n: PNode; value: Rope) =
|
||||
@@ -1143,8 +1143,8 @@ proc isNoReturn(m: BModule; s: PSym): bool {.inline.} =
|
||||
proc genProcAux*(m: BModule, prc: PSym) =
|
||||
var p = newProc(prc, m)
|
||||
var header = newRopeAppender()
|
||||
if m.config.backend == backendCpp and sfVirtual in prc.flags:
|
||||
genVirtualProcHeader(m, prc, header)
|
||||
if m.config.backend == backendCpp and {sfVirtual, sfConstructor} * prc.flags != {}:
|
||||
genMemberProcHeader(m, prc, header)
|
||||
else:
|
||||
genProcHeader(m, prc, header)
|
||||
var returnStmt: Rope = ""
|
||||
@@ -1162,7 +1162,7 @@ proc genProcAux*(m: BModule, prc: PSym) =
|
||||
internalError(m.config, prc.info, "proc has no result symbol")
|
||||
let resNode = prc.ast[resultPos]
|
||||
let res = resNode.sym # get result symbol
|
||||
if not isInvalidReturnType(m.config, prc.typ):
|
||||
if not isInvalidReturnType(m.config, prc.typ) and sfConstructor notin prc.flags:
|
||||
if sfNoInit in prc.flags: incl(res.flags, sfNoInit)
|
||||
if sfNoInit in prc.flags and p.module.compileToCpp and (let val = easyResultAsgn(procBody); val != nil):
|
||||
var decl = localVarDecl(p, resNode)
|
||||
@@ -1175,6 +1175,8 @@ proc genProcAux*(m: BModule, prc: PSym) =
|
||||
assert(res.loc.r != "")
|
||||
initLocalVar(p, res, immediateAsgn=false)
|
||||
returnStmt = ropecg(p.module, "\treturn $1;$n", [rdLoc(res.loc)])
|
||||
elif sfConstructor in prc.flags:
|
||||
fillLoc(resNode.sym.loc, locParam, resNode, "this", OnHeap)
|
||||
else:
|
||||
fillResult(p.config, resNode, prc.typ)
|
||||
assignParam(p, res, prc.typ[0])
|
||||
@@ -1252,7 +1254,7 @@ proc requiresExternC(m: BModule; sym: PSym): bool {.inline.} =
|
||||
|
||||
proc genProcPrototype(m: BModule, sym: PSym) =
|
||||
useHeader(m, sym)
|
||||
if lfNoDecl in sym.loc.flags or sfVirtual in sym.flags: return
|
||||
if lfNoDecl in sym.loc.flags or {sfVirtual, sfConstructor} * sym.flags != {}: return
|
||||
if lfDynamicLib in sym.loc.flags:
|
||||
if sym.itemId.module != m.module.position and
|
||||
not containsOrIncl(m.declaredThings, sym.id):
|
||||
|
||||
@@ -79,7 +79,7 @@ type
|
||||
procInstCache*: Table[ItemId, seq[LazyInstantiation]] # A symbol's ItemId.
|
||||
attachedOps*: array[TTypeAttachedOp, Table[ItemId, LazySym]] # Type ID, destructors, etc.
|
||||
methodsPerType*: Table[ItemId, seq[(int, LazySym)]] # Type ID, attached methods
|
||||
virtualProcsPerType*: Table[ItemId, seq[PSym]] # Type ID, attached virtual procs
|
||||
memberProcsPerType*: Table[ItemId, seq[PSym]] # Type ID, attached member procs (only c++, virtual and ctor so far)
|
||||
enumToStringProcs*: Table[ItemId, LazySym]
|
||||
emittedTypeInfo*: Table[string, FileIndex]
|
||||
|
||||
|
||||
@@ -971,8 +971,12 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
|
||||
# only supported for backwards compat, doesn't do anything anymore
|
||||
noVal(c, it)
|
||||
of wConstructor:
|
||||
noVal(c, it)
|
||||
incl(sym.flags, sfConstructor)
|
||||
if sfImportc notin sym.flags:
|
||||
sym.constraint = newEmptyStrNode(c, it, getOptionalStr(c, it, ""))
|
||||
sym.constraint.strVal = sym.constraint.strVal
|
||||
sym.flags.incl {sfExportc, sfMangleCpp}
|
||||
sym.typ.callConv = ccNoConvention
|
||||
of wHeader:
|
||||
var lib = getLib(c, libHeader, getStrLitNode(c, it))
|
||||
addToLib(lib, sym)
|
||||
|
||||
@@ -1654,6 +1654,16 @@ proc swapResult(n: PNode, sRes: PSym, dNode: PNode) =
|
||||
n[i] = dNode
|
||||
swapResult(n[i], sRes, dNode)
|
||||
|
||||
|
||||
proc addThis(c: PContext, n: PNode, t: PType, owner: TSymKind) =
|
||||
var s = newSym(skResult, getIdent(c.cache, "this"), c.idgen,
|
||||
getCurrOwner(c), n.info)
|
||||
s.typ = t
|
||||
incl(s.flags, sfUsed)
|
||||
c.p.resultSym = s
|
||||
n.add newSymNode(c.p.resultSym)
|
||||
addParamOrResult(c, c.p.resultSym, owner)
|
||||
|
||||
proc addResult(c: PContext, n: PNode, t: PType, owner: TSymKind) =
|
||||
template genResSym(s) =
|
||||
var s = newSym(skResult, getIdent(c.cache, "result"), c.idgen,
|
||||
@@ -2189,24 +2199,33 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||
if sfBorrow in s.flags and c.config.cmd notin cmdDocLike:
|
||||
result[bodyPos] = c.graph.emptyNode
|
||||
|
||||
if sfVirtual in s.flags:
|
||||
if {sfVirtual, sfConstructor} * s.flags != {} and sfImportc notin s.flags:
|
||||
let isVirtual = sfVirtual in s.flags
|
||||
let pragmaName = if isVirtual: "virtual" else: "constructor"
|
||||
if c.config.backend == backendCpp:
|
||||
if s.typ.sons.len < 2 and isVirtual:
|
||||
localError(c.config, n.info, "virtual must have at least one parameter")
|
||||
for son in s.typ.sons:
|
||||
if son!=nil and son.isMetaType:
|
||||
localError(c.config, n.info, "virtual unsupported for generic routine")
|
||||
|
||||
var typ = s.typ.sons[1]
|
||||
if typ.kind == tyPtr:
|
||||
localError(c.config, n.info, pragmaName & " unsupported for generic routine")
|
||||
var typ: PType
|
||||
if sfConstructor in s.flags:
|
||||
typ = s.typ.sons[0]
|
||||
if typ == nil or typ.kind != tyObject:
|
||||
localError(c.config, n.info, "constructor must return an object")
|
||||
else:
|
||||
typ = s.typ.sons[1]
|
||||
if typ.kind == tyPtr and isVirtual:
|
||||
typ = typ[0]
|
||||
if typ.kind != tyObject:
|
||||
localError(c.config, n.info, "virtual must be a non ref object type")
|
||||
localError(c.config, n.info, "virtual must be either ptr to object or object type.")
|
||||
if typ.owner.id == s.owner.id and c.module.id == s.owner.id:
|
||||
c.graph.virtualProcsPerType.mgetOrPut(typ.itemId, @[]).add s
|
||||
c.graph.memberProcsPerType.mgetOrPut(typ.itemId, @[]).add s
|
||||
else:
|
||||
localError(c.config, n.info,
|
||||
"virtual procs must be defined in the same scope as the type they are virtual for and it must be a top level scope")
|
||||
pragmaName & " procs must be defined in the same scope as the type they are virtual for and it must be a top level scope")
|
||||
else:
|
||||
localError(c.config, n.info, "virtual procs are only supported in C++")
|
||||
localError(c.config, n.info, pragmaName & " procs are only supported in C++")
|
||||
|
||||
if n[bodyPos].kind != nkEmpty and sfError notin s.flags:
|
||||
# for DLL generation we allow sfImportc to have a body, for use in VM
|
||||
@@ -2232,15 +2251,19 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||
# Macros and Templates can have generic parameters, but they are only
|
||||
# used for overload resolution (there is no instantiation of the symbol)
|
||||
if s.kind notin {skMacro, skTemplate} and s.magic == mNone: paramsTypeCheck(c, s.typ)
|
||||
|
||||
maybeAddResult(c, s, n)
|
||||
let resultType =
|
||||
if s.kind == skMacro:
|
||||
sysTypeFromName(c.graph, n.info, "NimNode")
|
||||
elif not isInlineIterator(s.typ):
|
||||
s.typ[0]
|
||||
else:
|
||||
nil
|
||||
var resultType: PType
|
||||
if sfConstructor in s.flags:
|
||||
resultType = makePtrType(c, s.typ[0])
|
||||
addThis(c, n, resultType, skProc)
|
||||
else:
|
||||
maybeAddResult(c, s, n)
|
||||
resultType =
|
||||
if s.kind == skMacro:
|
||||
sysTypeFromName(c.graph, n.info, "NimNode")
|
||||
elif not isInlineIterator(s.typ):
|
||||
s.typ[0]
|
||||
else:
|
||||
nil
|
||||
# semantic checking also needed with importc in case used in VM
|
||||
s.ast[bodyPos] = hloBody(c, semProcBody(c, n[bodyPos], resultType))
|
||||
# unfortunately we cannot skip this step when in 'system.compiles'
|
||||
|
||||
@@ -75,10 +75,10 @@ const
|
||||
const
|
||||
signMask*: BitsType = not (not BitsType(0) shr 1)
|
||||
|
||||
proc constructDouble*(bits: BitsType): Double {.constructor.} =
|
||||
proc constructDouble*(bits: BitsType): Double =
|
||||
result.bits = bits
|
||||
|
||||
proc constructDouble*(value: ValueType): Double {.constructor.} =
|
||||
proc constructDouble*(value: ValueType): Double =
|
||||
result.bits = cast[typeof(result.bits)](value)
|
||||
|
||||
proc physicalSignificand*(this: Double): BitsType {.noSideEffect.} =
|
||||
|
||||
@@ -39,10 +39,10 @@ const
|
||||
exponentMask: BitsType = maxIeeeExponent shl (significandSize - 1)
|
||||
signMask: BitsType = not (not BitsType(0) shr 1)
|
||||
|
||||
proc constructSingle(bits: BitsType): Single {.constructor.} =
|
||||
proc constructSingle(bits: BitsType): Single =
|
||||
result.bits = bits
|
||||
|
||||
proc constructSingle(value: ValueType): Single {.constructor.} =
|
||||
proc constructSingle(value: ValueType): Single =
|
||||
result.bits = cast[typeof(result.bits)](value)
|
||||
|
||||
proc physicalSignificand(this: Single): BitsType {.noSideEffect.} =
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
discard """
|
||||
targets: "cpp"
|
||||
cmd: "nim cpp $file"
|
||||
output: '''
|
||||
1
|
||||
'''
|
||||
"""
|
||||
|
||||
{.emit:"""/*TYPESECTION*/
|
||||
@@ -15,10 +18,38 @@ struct CppClass {
|
||||
};
|
||||
""".}
|
||||
|
||||
type CppClass* {.importcpp.} = object
|
||||
type CppClass* {.importcpp, inheritable.} = object
|
||||
x: int32
|
||||
y: int32
|
||||
|
||||
proc makeCppClass(x, y: int32): CppClass {.importcpp: "CppClass(@)", constructor.}
|
||||
#test globals are init with the constructor call
|
||||
var shouldCompile {.used.} = makeCppClass(1, 2)
|
||||
|
||||
var shouldCompile = makeCppClass(1, 2)
|
||||
proc newCpp*[T](): ptr T {.importcpp:"new '*0()".}
|
||||
|
||||
#creation
|
||||
type NimClassNoNarent* = object
|
||||
x: int32
|
||||
|
||||
proc makeNimClassNoParent(x:int32): NimClassNoNarent {. constructor.} =
|
||||
this.x = x
|
||||
discard
|
||||
|
||||
let nimClassNoParent = makeNimClassNoParent(1)
|
||||
echo nimClassNoParent.x #acess to this just fine. Notice the field will appear last because we are dealing with constructor calls here
|
||||
|
||||
var nimClassNoParentDef {.used.}: NimClassNoNarent #test has a default constructor.
|
||||
|
||||
#inheritance
|
||||
type NimClass* = object of CppClass
|
||||
|
||||
proc makeNimClass(x:int32): NimClass {. constructor:"NimClass('1 #1) : CppClass(0, #1) ".} =
|
||||
this.x = x
|
||||
|
||||
#optinially define the default constructor so we get rid of the cpp warn and we can declare the obj (note: default constructor of 'tyObject_NimClass__apRyyO8cfRsZtsldq1rjKA' is implicitly deleted because base class 'CppClass' has no default constructor)
|
||||
proc makeCppClass(): NimClass {. constructor: "NimClass() : CppClass(0, 0) ".} =
|
||||
this.x = 1
|
||||
|
||||
let nimClass = makeNimClass(1)
|
||||
var nimClassDef {.used.}: NimClass #since we explictly defined the default constructor we can declare the obj
|
||||
Reference in New Issue
Block a user