parent
2f1a1b7106
commit
0f868b587b
4 changed files with 99 additions and 62 deletions
|
|
@ -2708,7 +2708,8 @@ proc getDefaultValue(p: BProc; typ: PType; info: TLineInfo): Rope =
|
||||||
else:
|
else:
|
||||||
globalError(p.config, info, "cannot create null element for: " & $t.kind)
|
globalError(p.config, info, "cannot create null element for: " & $t.kind)
|
||||||
|
|
||||||
proc getNullValueAux(p: BProc; t: PType; obj, cons: PNode, result: var Rope; count: var int) =
|
proc getNullValueAux(p: BProc; t: PType; obj, cons: PNode,
|
||||||
|
result: var Rope; count: var int) =
|
||||||
case obj.kind
|
case obj.kind
|
||||||
of nkRecList:
|
of nkRecList:
|
||||||
for it in obj.sons:
|
for it in obj.sons:
|
||||||
|
|
@ -2734,7 +2735,8 @@ proc getNullValueAux(p: BProc; t: PType; obj, cons: PNode, result: var Rope; cou
|
||||||
else:
|
else:
|
||||||
localError(p.config, cons.info, "cannot create null element for: " & $obj)
|
localError(p.config, cons.info, "cannot create null element for: " & $obj)
|
||||||
|
|
||||||
proc getNullValueAuxT(p: BProc; orig, t: PType; obj, cons: PNode, result: var Rope; count: var int) =
|
proc getNullValueAuxT(p: BProc; orig, t: PType; obj, cons: PNode,
|
||||||
|
result: var Rope; count: var int) =
|
||||||
var base = t.sons[0]
|
var base = t.sons[0]
|
||||||
let oldRes = result
|
let oldRes = result
|
||||||
if not p.module.compileToCpp: result.add "{"
|
if not p.module.compileToCpp: result.add "{"
|
||||||
|
|
|
||||||
|
|
@ -329,6 +329,9 @@ proc getSimpleTypeDesc(m: BModule, typ: PType): Rope =
|
||||||
addAbiCheck(m, typ, result)
|
addAbiCheck(m, typ, result)
|
||||||
|
|
||||||
proc pushType(m: BModule, typ: PType) =
|
proc pushType(m: BModule, typ: PType) =
|
||||||
|
for i in 0 .. high(m.typeStack):
|
||||||
|
# pointer equality is good enough here:
|
||||||
|
if m.typeStack[i] == typ: return
|
||||||
add(m.typeStack, typ)
|
add(m.typeStack, typ)
|
||||||
|
|
||||||
proc getTypePre(m: BModule, typ: PType; sig: SigHash): Rope =
|
proc getTypePre(m: BModule, typ: PType; sig: SigHash): Rope =
|
||||||
|
|
@ -384,14 +387,53 @@ proc getTypeDescWeak(m: BModule; t: PType; check: var IntSet): Rope =
|
||||||
result = getTypeForward(m, t, hashType(t))
|
result = getTypeForward(m, t, hashType(t))
|
||||||
pushType(m, t)
|
pushType(m, t)
|
||||||
of tySequence:
|
of tySequence:
|
||||||
|
let sig = hashType(t)
|
||||||
if m.config.selectedGC == gcDestructors:
|
if m.config.selectedGC == gcDestructors:
|
||||||
result = getTypeDescAux(m, t, check)
|
if skipTypes(etB.sons[0], typedescInst).kind == tyEmpty:
|
||||||
|
internalError(m.config, "cannot map the empty seq type to a C type")
|
||||||
|
|
||||||
|
result = cacheGetType(m.forwTypeCache, sig)
|
||||||
|
if result == nil:
|
||||||
|
result = getTypeName(m, t, sig)
|
||||||
|
if not isImportedType(t):
|
||||||
|
m.forwTypeCache[sig] = result
|
||||||
|
addForwardStructFormat(m, rope"struct", result)
|
||||||
|
let payload = result & "_Content"
|
||||||
|
addForwardStructFormat(m, rope"struct", payload)
|
||||||
|
|
||||||
|
if cacheGetType(m.typeCache, sig) == nil:
|
||||||
|
m.typeCache[sig] = result
|
||||||
|
#echo "adding ", sig, " ", typeToString(t), " ", m.module.name.s
|
||||||
|
appcg(m, m.s[cfsTypes],
|
||||||
|
"struct $1 {$n" &
|
||||||
|
" NI len; $1_Content* p;$n" &
|
||||||
|
"};$n", [result])
|
||||||
else:
|
else:
|
||||||
result = getTypeForward(m, t, hashType(t)) & seqStar(m)
|
result = getTypeForward(m, t, sig) & seqStar(m)
|
||||||
pushType(m, t)
|
pushType(m, t)
|
||||||
else:
|
else:
|
||||||
result = getTypeDescAux(m, t, check)
|
result = getTypeDescAux(m, t, check)
|
||||||
|
|
||||||
|
proc getSeqPayloadType(m: BModule; t: PType): Rope =
|
||||||
|
var check = initIntSet()
|
||||||
|
result = getTypeDescWeak(m, t, check)
|
||||||
|
#result = getTypeForward(m, t, hashType(t)) & "_Content"
|
||||||
|
|
||||||
|
proc seqV2ContentType(m: BModule; t: PType; check: var IntSet) =
|
||||||
|
let sig = hashType(t)
|
||||||
|
let result = cacheGetType(m.typeCache, sig)
|
||||||
|
if result == nil:
|
||||||
|
discard getTypeDescAux(m, t, check)
|
||||||
|
else:
|
||||||
|
# little hack for now to prevent multiple definitions of the same
|
||||||
|
# Seq_Content:
|
||||||
|
appcg(m, m.s[cfsTypes], """
|
||||||
|
$3ifndef $2_Content_PP
|
||||||
|
$3define $2_Content_PP
|
||||||
|
struct $2_Content { NI cap;#AllocatorObj* allocator;$1 data[SEQ_DECL_SIZE];};
|
||||||
|
$3endif
|
||||||
|
""", [getTypeDescAux(m, t.skipTypes(abstractInst).sons[0], check), result, rope"#"])
|
||||||
|
|
||||||
proc paramStorageLoc(param: PSym): TStorageLoc =
|
proc paramStorageLoc(param: PSym): TStorageLoc =
|
||||||
if param.typ.skipTypes({tyVar, tyLent, tyTypeDesc}).kind notin {
|
if param.typ.skipTypes({tyVar, tyLent, tyTypeDesc}).kind notin {
|
||||||
tyArray, tyOpenArray, tyVarargs}:
|
tyArray, tyOpenArray, tyVarargs}:
|
||||||
|
|
@ -513,7 +555,7 @@ proc genRecordFieldsAux(m: BModule, n: PNode,
|
||||||
if fieldType.kind == tyUncheckedArray:
|
if fieldType.kind == tyUncheckedArray:
|
||||||
addf(result, "$1 $2[SEQ_DECL_SIZE];$n",
|
addf(result, "$1 $2[SEQ_DECL_SIZE];$n",
|
||||||
[getTypeDescAux(m, fieldType.elemType, check), sname])
|
[getTypeDescAux(m, fieldType.elemType, check), sname])
|
||||||
elif fieldType.kind == tySequence and m.config.selectedGC != gcDestructors:
|
elif fieldType.kind == tySequence:
|
||||||
# we need to use a weak dependency here for trecursive_table.
|
# we need to use a weak dependency here for trecursive_table.
|
||||||
addf(result, "$1 $2;$n", [getTypeDescWeak(m, field.loc.t, check), sname])
|
addf(result, "$1 $2;$n", [getTypeDescWeak(m, field.loc.t, check), sname])
|
||||||
elif field.bitsize != 0:
|
elif field.bitsize != 0:
|
||||||
|
|
@ -627,15 +669,6 @@ proc resolveStarsInCppType(typ: PType, idx, stars: int): PType =
|
||||||
result = if result.kind == tyGenericInst: result.sons[1]
|
result = if result.kind == tyGenericInst: result.sons[1]
|
||||||
else: result.elemType
|
else: result.elemType
|
||||||
|
|
||||||
proc getSeqPayloadType(m: BModule; t: PType): Rope =
|
|
||||||
result = getTypeForward(m, t, hashType(t)) & "_Content"
|
|
||||||
when false:
|
|
||||||
var check = initIntSet()
|
|
||||||
# XXX remove this duplication:
|
|
||||||
appcg(m, m.s[cfsSeqTypes],
|
|
||||||
"struct $2_Content { NI cap; void* allocator; $1 data[SEQ_DECL_SIZE]; };$n",
|
|
||||||
[getTypeDescAux(m, t.sons[0], check), result])
|
|
||||||
|
|
||||||
proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope =
|
proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope =
|
||||||
# returns only the type's name
|
# returns only the type's name
|
||||||
var t = origTyp.skipTypes(irrelevantForBackend-{tyOwned})
|
var t = origTyp.skipTypes(irrelevantForBackend-{tyOwned})
|
||||||
|
|
@ -675,11 +708,15 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope =
|
||||||
result = name & star
|
result = name & star
|
||||||
m.typeCache[sig] = result
|
m.typeCache[sig] = result
|
||||||
of tySequence:
|
of tySequence:
|
||||||
# no restriction! We have a forward declaration for structs
|
if m.config.selectedGC == gcDestructors:
|
||||||
let name = getTypeForward(m, et, hashType et)
|
result = getTypeDescWeak(m, et, check) & star
|
||||||
result = name & seqStar(m) & star
|
m.typeCache[sig] = result
|
||||||
m.typeCache[sig] = result
|
else:
|
||||||
pushType(m, et)
|
# no restriction! We have a forward declaration for structs
|
||||||
|
let name = getTypeForward(m, et, hashType et)
|
||||||
|
result = name & seqStar(m) & star
|
||||||
|
m.typeCache[sig] = result
|
||||||
|
pushType(m, et)
|
||||||
else:
|
else:
|
||||||
# else we have a strong dependency :-(
|
# else we have a strong dependency :-(
|
||||||
result = getTypeDescAux(m, et, check) & star
|
result = getTypeDescAux(m, et, check) & star
|
||||||
|
|
@ -731,29 +768,25 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope =
|
||||||
"void* ClE_0;$n} $1;$n",
|
"void* ClE_0;$n} $1;$n",
|
||||||
[result, rettype, desc])
|
[result, rettype, desc])
|
||||||
of tySequence:
|
of tySequence:
|
||||||
# we cannot use getTypeForward here because then t would be associated
|
if m.config.selectedGC == gcDestructors:
|
||||||
# with the name of the struct, not with the pointer to the struct:
|
result = getTypeDescWeak(m, t, check)
|
||||||
result = cacheGetType(m.forwTypeCache, sig)
|
else:
|
||||||
if result == nil:
|
# we cannot use getTypeForward here because then t would be associated
|
||||||
result = getTypeName(m, origTyp, sig)
|
# with the name of the struct, not with the pointer to the struct:
|
||||||
|
result = cacheGetType(m.forwTypeCache, sig)
|
||||||
|
if result == nil:
|
||||||
|
result = getTypeName(m, origTyp, sig)
|
||||||
|
if not isImportedType(t):
|
||||||
|
addForwardStructFormat(m, structOrUnion(t), result)
|
||||||
|
m.forwTypeCache[sig] = result
|
||||||
|
assert(cacheGetType(m.typeCache, sig) == nil)
|
||||||
|
m.typeCache[sig] = result & seqStar(m)
|
||||||
if not isImportedType(t):
|
if not isImportedType(t):
|
||||||
addForwardStructFormat(m, structOrUnion(t), result)
|
if skipTypes(t.sons[0], typedescInst).kind != tyEmpty:
|
||||||
m.forwTypeCache[sig] = result
|
const
|
||||||
assert(cacheGetType(m.typeCache, sig) == nil)
|
cppSeq = "struct $2 : #TGenericSeq {$n"
|
||||||
m.typeCache[sig] = result & seqStar(m)
|
cSeq = "struct $2 {$n" &
|
||||||
if not isImportedType(t):
|
" #TGenericSeq Sup;$n"
|
||||||
if skipTypes(t.sons[0], typedescInst).kind != tyEmpty:
|
|
||||||
const
|
|
||||||
cppSeq = "struct $2 : #TGenericSeq {$n"
|
|
||||||
cSeq = "struct $2 {$n" &
|
|
||||||
" #TGenericSeq Sup;$n"
|
|
||||||
if m.config.selectedGC == gcDestructors:
|
|
||||||
appcg(m, m.s[cfsTypes],
|
|
||||||
"typedef struct{ NI cap;#AllocatorObj* allocator;$1 data[SEQ_DECL_SIZE];}$2_Content;$n" &
|
|
||||||
"struct $2 {$n" &
|
|
||||||
" NI len; $2_Content* p;$n" &
|
|
||||||
"};$n", [getTypeDescAux(m, t.sons[0], check), result])
|
|
||||||
else:
|
|
||||||
if m.compileToCpp:
|
if m.compileToCpp:
|
||||||
appcg(m, m.s[cfsSeqTypes],
|
appcg(m, m.s[cfsSeqTypes],
|
||||||
cppSeq & " $1 data[SEQ_DECL_SIZE];$n" &
|
cppSeq & " $1 data[SEQ_DECL_SIZE];$n" &
|
||||||
|
|
@ -762,11 +795,9 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope =
|
||||||
appcg(m, m.s[cfsSeqTypes],
|
appcg(m, m.s[cfsSeqTypes],
|
||||||
cSeq & " $1 data[SEQ_DECL_SIZE];$n" &
|
cSeq & " $1 data[SEQ_DECL_SIZE];$n" &
|
||||||
"};$n", [getTypeDescAux(m, t.sons[0], check), result])
|
"};$n", [getTypeDescAux(m, t.sons[0], check), result])
|
||||||
elif m.config.selectedGC == gcDestructors:
|
else:
|
||||||
internalError(m.config, "cannot map the empty seq type to a C type")
|
result = rope("TGenericSeq")
|
||||||
else:
|
add(result, seqStar(m))
|
||||||
result = rope("TGenericSeq")
|
|
||||||
add(result, seqStar(m))
|
|
||||||
of tyUncheckedArray:
|
of tyUncheckedArray:
|
||||||
result = getTypeName(m, origTyp, sig)
|
result = getTypeName(m, origTyp, sig)
|
||||||
m.typeCache[sig] = result
|
m.typeCache[sig] = result
|
||||||
|
|
@ -830,21 +861,8 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope =
|
||||||
m.typeCache[sig] = typedefName
|
m.typeCache[sig] = typedefName
|
||||||
result = typedefName
|
result = typedefName
|
||||||
else:
|
else:
|
||||||
when false:
|
|
||||||
if t.sym != nil and t.sym.name.s == "KeyValuePair":
|
|
||||||
if t == origTyp:
|
|
||||||
echo "wtf: came here"
|
|
||||||
writeStackTrace()
|
|
||||||
quit 1
|
|
||||||
result = cacheGetType(m.forwTypeCache, sig)
|
result = cacheGetType(m.forwTypeCache, sig)
|
||||||
if result == nil:
|
if result == nil:
|
||||||
when false:
|
|
||||||
if t.sym != nil and t.sym.name.s == "KeyValuePair":
|
|
||||||
# or {sfImportc, sfExportc} * t.sym.flags == {}:
|
|
||||||
if t.loc.r != nil:
|
|
||||||
echo t.kind, " ", hashType t
|
|
||||||
echo origTyp.kind, " ", sig
|
|
||||||
assert t.loc.r == nil
|
|
||||||
result = getTypeName(m, origTyp, sig)
|
result = getTypeName(m, origTyp, sig)
|
||||||
m.forwTypeCache[sig] = result
|
m.forwTypeCache[sig] = result
|
||||||
if not isImportedType(t):
|
if not isImportedType(t):
|
||||||
|
|
@ -903,8 +921,13 @@ proc getClosureType(m: BModule, t: PType, kind: TClosureTypeKind): Rope =
|
||||||
|
|
||||||
proc finishTypeDescriptions(m: BModule) =
|
proc finishTypeDescriptions(m: BModule) =
|
||||||
var i = 0
|
var i = 0
|
||||||
|
var check = initIntSet()
|
||||||
while i < len(m.typeStack):
|
while i < len(m.typeStack):
|
||||||
discard getTypeDesc(m, m.typeStack[i])
|
let t = m.typeStack[i]
|
||||||
|
if m.config.selectedGC == gcDestructors and t.skipTypes(abstractInst).kind == tySequence:
|
||||||
|
seqV2ContentType(m, t, check)
|
||||||
|
else:
|
||||||
|
discard getTypeDescAux(m, t, check)
|
||||||
inc(i)
|
inc(i)
|
||||||
|
|
||||||
template cgDeclFrmt*(s: PSym): string =
|
template cgDeclFrmt*(s: PSym): string =
|
||||||
|
|
|
||||||
|
|
@ -780,7 +780,7 @@ proc cgsym(m: BModule, name: string): Rope =
|
||||||
# we're picky here for the system module too:
|
# we're picky here for the system module too:
|
||||||
rawMessage(m.config, errGenerated, "system module needs: " & name)
|
rawMessage(m.config, errGenerated, "system module needs: " & name)
|
||||||
result = sym.loc.r
|
result = sym.loc.r
|
||||||
if m.hcrOn and sym != nil and sym.kind in skProc..skIterator:
|
if m.hcrOn and sym != nil and sym.kind in {skProc..skIterator}:
|
||||||
result.addActualPrefixForHCR(m.module, sym)
|
result.addActualPrefixForHCR(m.module, sym)
|
||||||
|
|
||||||
proc generateHeaders(m: BModule) =
|
proc generateHeaders(m: BModule) =
|
||||||
|
|
|
||||||
|
|
@ -20,5 +20,17 @@ proc main =
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|
||||||
|
# bug #11563
|
||||||
|
type
|
||||||
|
MyTypeType = enum
|
||||||
|
Zero, One
|
||||||
|
MyType = object
|
||||||
|
case kind: MyTypeType
|
||||||
|
of Zero:
|
||||||
|
s*: seq[MyType]
|
||||||
|
of One:
|
||||||
|
x*: int
|
||||||
|
var t: MyType
|
||||||
|
|
||||||
let (a, d) = allocCounters()
|
let (a, d) = allocCounters()
|
||||||
discard cprintf("%ld %ld new: %ld\n", a, d, allocs)
|
discard cprintf("%ld %ld new: %ld\n", a, d, allocs)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue