Nim can interface with C++ templates
This commit is contained in:
parent
6004280522
commit
22318ce8ac
1 changed files with 63 additions and 46 deletions
|
|
@ -199,7 +199,7 @@ const
|
||||||
|
|
||||||
proc cacheGetType(tab: TIdTable, key: PType): PRope =
|
proc cacheGetType(tab: TIdTable, key: PType): PRope =
|
||||||
# returns nil if we need to declare this type
|
# returns nil if we need to declare this type
|
||||||
# since types are now unique via the ``GetUniqueType`` mechanism, this slow
|
# since types are now unique via the ``getUniqueType`` mechanism, this slow
|
||||||
# linear search is not necessary anymore:
|
# linear search is not necessary anymore:
|
||||||
result = PRope(idTableGet(tab, key))
|
result = PRope(idTableGet(tab, key))
|
||||||
|
|
||||||
|
|
@ -390,7 +390,7 @@ proc genRecordFieldsAux(m: BModule, n: PNode,
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
app(result, genRecordFieldsAux(m, n.sons[i], accessExpr, rectype, check))
|
app(result, genRecordFieldsAux(m, n.sons[i], accessExpr, rectype, check))
|
||||||
of nkRecCase:
|
of nkRecCase:
|
||||||
if (n.sons[0].kind != nkSym): internalError(n.info, "genRecordFieldsAux")
|
if n.sons[0].kind != nkSym: internalError(n.info, "genRecordFieldsAux")
|
||||||
app(result, genRecordFieldsAux(m, n.sons[0], accessExpr, rectype, check))
|
app(result, genRecordFieldsAux(m, n.sons[0], accessExpr, rectype, check))
|
||||||
uname = toRope(mangle(n.sons[0].sym.name.s) & 'U')
|
uname = toRope(mangle(n.sons[0].sym.name.s) & 'U')
|
||||||
if accessExpr != nil: ae = ropef("$1.$2", [accessExpr, uname])
|
if accessExpr != nil: ae = ropef("$1.$2", [accessExpr, uname])
|
||||||
|
|
@ -421,12 +421,14 @@ proc genRecordFieldsAux(m: BModule, n: PNode,
|
||||||
if accessExpr != nil: ae = ropef("$1.$2", [accessExpr, sname])
|
if accessExpr != nil: ae = ropef("$1.$2", [accessExpr, sname])
|
||||||
else: ae = sname
|
else: ae = sname
|
||||||
fillLoc(field.loc, locField, field.typ, ae, OnUnknown)
|
fillLoc(field.loc, locField, field.typ, ae, OnUnknown)
|
||||||
let fieldType = field.loc.t
|
let fieldType = field.loc.t.skipTypes(abstractInst)
|
||||||
if fieldType.kind == tyArray and tfUncheckedArray in fieldType.flags:
|
if fieldType.kind == tyArray and tfUncheckedArray in fieldType.flags:
|
||||||
appf(result, "$1 $2[SEQ_DECL_SIZE];$n",
|
appf(result, "$1 $2[SEQ_DECL_SIZE];$n",
|
||||||
[getTypeDescAux(m, fieldType.elemType, check), sname])
|
[getTypeDescAux(m, fieldType.elemType, check), sname])
|
||||||
else:
|
else:
|
||||||
appf(result, "$1 $2;$n", [getTypeDescAux(m, fieldType, check), sname])
|
# don't use fieldType here because we need the
|
||||||
|
# tyGenericInst for C++ template support
|
||||||
|
appf(result, "$1 $2;$n", [getTypeDescAux(m, field.loc.t, check), sname])
|
||||||
else: internalError(n.info, "genRecordFieldsAux()")
|
else: internalError(n.info, "genRecordFieldsAux()")
|
||||||
|
|
||||||
proc getRecordFields(m: BModule, typ: PType, check: var IntSet): PRope =
|
proc getRecordFields(m: BModule, typ: PType, check: var IntSet): PRope =
|
||||||
|
|
@ -486,11 +488,7 @@ proc pushType(m: BModule, typ: PType) =
|
||||||
|
|
||||||
proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): PRope =
|
proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): PRope =
|
||||||
# returns only the type's name
|
# returns only the type's name
|
||||||
var
|
var t = getUniqueType(typ)
|
||||||
name, rettype, desc, recdesc: PRope
|
|
||||||
n: BiggestInt
|
|
||||||
t, et: PType
|
|
||||||
t = getUniqueType(typ)
|
|
||||||
if t == nil: internalError("getTypeDescAux: t == nil")
|
if t == nil: internalError("getTypeDescAux: t == nil")
|
||||||
if t.sym != nil: useHeader(m, t.sym)
|
if t.sym != nil: useHeader(m, t.sym)
|
||||||
result = getTypePre(m, t)
|
result = getTypePre(m, t)
|
||||||
|
|
@ -502,35 +500,42 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): PRope =
|
||||||
# C type generation into an analysis and a code generation phase somehow.
|
# C type generation into an analysis and a code generation phase somehow.
|
||||||
case t.kind
|
case t.kind
|
||||||
of tyRef, tyPtr, tyVar:
|
of tyRef, tyPtr, tyVar:
|
||||||
et = getUniqueType(t.lastSon)
|
var et = t.lastSon
|
||||||
if et.kind in {tyArrayConstr, tyArray, tyOpenArray, tyVarargs}:
|
var etB = et.skipTypes(abstractInst)
|
||||||
|
if etB.kind in {tyArrayConstr, tyArray, tyOpenArray, tyVarargs}:
|
||||||
# this is correct! sets have no proper base type, so we treat
|
# this is correct! sets have no proper base type, so we treat
|
||||||
# ``var set[char]`` in `getParamTypeDesc`
|
# ``var set[char]`` in `getParamTypeDesc`
|
||||||
et = getUniqueType(elemType(et))
|
et = elemType(etB)
|
||||||
case et.kind
|
etB = et.skipTypes(abstractInst)
|
||||||
of tyObject, tyTuple:
|
case etB.kind
|
||||||
|
of tyObject, tyTuple:
|
||||||
|
if isImportedCppType(etB) and et.kind == tyGenericInst:
|
||||||
|
result = con(getTypeDescAux(m, et, check), "*")
|
||||||
|
else:
|
||||||
|
# no restriction! We have a forward declaration for structs
|
||||||
|
let x = getUniqueType(etB)
|
||||||
|
let name = getTypeForward(m, x)
|
||||||
|
result = con(name, "*")
|
||||||
|
idTablePut(m.typeCache, t, result)
|
||||||
|
pushType(m, x)
|
||||||
|
of tySequence:
|
||||||
# no restriction! We have a forward declaration for structs
|
# no restriction! We have a forward declaration for structs
|
||||||
name = getTypeForward(m, et)
|
let x = getUniqueType(etB)
|
||||||
result = con(name, "*")
|
let name = getTypeForward(m, x)
|
||||||
idTablePut(m.typeCache, t, result)
|
|
||||||
pushType(m, et)
|
|
||||||
of tySequence:
|
|
||||||
# no restriction! We have a forward declaration for structs
|
|
||||||
name = getTypeForward(m, et)
|
|
||||||
result = con(name, "**")
|
result = con(name, "**")
|
||||||
idTablePut(m.typeCache, t, result)
|
idTablePut(m.typeCache, t, result)
|
||||||
pushType(m, et)
|
pushType(m, x)
|
||||||
else:
|
else:
|
||||||
# else we have a strong dependency :-(
|
# else we have a strong dependency :-(
|
||||||
result = con(getTypeDescAux(m, et, check), "*")
|
result = con(getTypeDescAux(m, et, check), "*")
|
||||||
idTablePut(m.typeCache, t, result)
|
idTablePut(m.typeCache, t, result)
|
||||||
of tyOpenArray, tyVarargs:
|
of tyOpenArray, tyVarargs:
|
||||||
et = getUniqueType(t.sons[0])
|
result = con(getTypeDescAux(m, t.sons[0], check), "*")
|
||||||
result = con(getTypeDescAux(m, et, check), "*")
|
|
||||||
idTablePut(m.typeCache, t, result)
|
idTablePut(m.typeCache, t, result)
|
||||||
of tyProc:
|
of tyProc:
|
||||||
result = getTypeName(t)
|
result = getTypeName(t)
|
||||||
idTablePut(m.typeCache, t, result)
|
idTablePut(m.typeCache, t, result)
|
||||||
|
var rettype, desc: PRope
|
||||||
genProcParams(m, t, rettype, desc, check)
|
genProcParams(m, t, rettype, desc, check)
|
||||||
if not isImportedType(t):
|
if not isImportedType(t):
|
||||||
if t.callConv != ccClosure: # procedure vars may need a closure!
|
if t.callConv != ccClosure: # procedure vars may need a closure!
|
||||||
|
|
@ -545,7 +550,7 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): PRope =
|
||||||
# we cannot use getTypeForward here because then t would be associated
|
# we cannot use getTypeForward here because then t would be associated
|
||||||
# with the name of the struct, not with the pointer to the struct:
|
# with the name of the struct, not with the pointer to the struct:
|
||||||
result = cacheGetType(m.forwTypeCache, t)
|
result = cacheGetType(m.forwTypeCache, t)
|
||||||
if result == nil:
|
if result == nil:
|
||||||
result = getTypeName(t)
|
result = getTypeName(t)
|
||||||
if not isImportedType(t):
|
if not isImportedType(t):
|
||||||
appf(m.s[cfsForwardTypes], getForwardStructFormat(m),
|
appf(m.s[cfsForwardTypes], getForwardStructFormat(m),
|
||||||
|
|
@ -567,27 +572,39 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): PRope =
|
||||||
result = toRope("TGenericSeq")
|
result = toRope("TGenericSeq")
|
||||||
app(result, "*")
|
app(result, "*")
|
||||||
of tyArrayConstr, tyArray:
|
of tyArrayConstr, tyArray:
|
||||||
n = lengthOrd(t)
|
var n: BiggestInt = lengthOrd(t)
|
||||||
if n <= 0:
|
if n <= 0: n = 1 # make an array of at least one element
|
||||||
n = 1 # make an array of at least one element
|
|
||||||
result = getTypeName(t)
|
result = getTypeName(t)
|
||||||
idTablePut(m.typeCache, t, result)
|
idTablePut(m.typeCache, t, result)
|
||||||
if not isImportedType(t):
|
if not isImportedType(t):
|
||||||
|
let foo = getTypeDescAux(m, t.sons[1], check)
|
||||||
appf(m.s[cfsTypes], "typedef $1 $2[$3];$n",
|
appf(m.s[cfsTypes], "typedef $1 $2[$3];$n",
|
||||||
[getTypeDescAux(m, t.sons[1], check), result, toRope(n)])
|
[foo, result, toRope(n)])
|
||||||
of tyObject, tyTuple:
|
of tyObject, tyTuple:
|
||||||
result = cacheGetType(m.forwTypeCache, t)
|
if isImportedCppType(t) and typ.kind == tyGenericInst:
|
||||||
if result == nil:
|
# for instantiated templates we do not go through the type cache as the
|
||||||
result = getTypeName(t)
|
# the type cache is not aware of 'tyGenericInst'.
|
||||||
if not isImportedType(t):
|
result = getTypeName(t).con("<")
|
||||||
appf(m.s[cfsForwardTypes], getForwardStructFormat(m),
|
for i in 1 .. typ.len-2:
|
||||||
[structOrUnion(t), result])
|
if i > 1: result.app(", ")
|
||||||
idTablePut(m.forwTypeCache, t, result)
|
result.app(getTypeDescAux(m, typ.sons[i], check))
|
||||||
idTablePut(m.typeCache, t, result) # always call for sideeffects:
|
result.app("> ")
|
||||||
if t.kind != tyTuple: recdesc = getRecordDesc(m, t, result, check)
|
# always call for sideeffects:
|
||||||
else: recdesc = getTupleDesc(m, t, result, check)
|
assert t.kind != tyTuple
|
||||||
if not isImportedType(t): app(m.s[cfsTypes], recdesc)
|
discard getRecordDesc(m, t, result, check)
|
||||||
of tySet:
|
else:
|
||||||
|
result = cacheGetType(m.forwTypeCache, t)
|
||||||
|
if result == nil:
|
||||||
|
result = getTypeName(t)
|
||||||
|
if not isImportedType(t):
|
||||||
|
appf(m.s[cfsForwardTypes], getForwardStructFormat(m),
|
||||||
|
[structOrUnion(t), result])
|
||||||
|
idTablePut(m.forwTypeCache, t, result)
|
||||||
|
idTablePut(m.typeCache, t, result) # always call for sideeffects:
|
||||||
|
let recdesc = if t.kind != tyTuple: getRecordDesc(m, t, result, check)
|
||||||
|
else: getTupleDesc(m, t, result, check)
|
||||||
|
if not isImportedType(t): app(m.s[cfsTypes], recdesc)
|
||||||
|
of tySet:
|
||||||
case int(getSize(t))
|
case int(getSize(t))
|
||||||
of 1: result = toRope("NU8")
|
of 1: result = toRope("NU8")
|
||||||
of 2: result = toRope("NU16")
|
of 2: result = toRope("NU16")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue