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:
|
||||
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
|
||||
of nkRecList:
|
||||
for it in obj.sons:
|
||||
|
|
@ -2734,7 +2735,8 @@ proc getNullValueAux(p: BProc; t: PType; obj, cons: PNode, result: var Rope; cou
|
|||
else:
|
||||
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]
|
||||
let oldRes = result
|
||||
if not p.module.compileToCpp: result.add "{"
|
||||
|
|
|
|||
|
|
@ -329,6 +329,9 @@ proc getSimpleTypeDesc(m: BModule, typ: PType): Rope =
|
|||
addAbiCheck(m, typ, result)
|
||||
|
||||
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)
|
||||
|
||||
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))
|
||||
pushType(m, t)
|
||||
of tySequence:
|
||||
let sig = hashType(t)
|
||||
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:
|
||||
result = getTypeForward(m, t, hashType(t)) & seqStar(m)
|
||||
pushType(m, t)
|
||||
result = getTypeForward(m, t, sig) & seqStar(m)
|
||||
pushType(m, t)
|
||||
else:
|
||||
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 =
|
||||
if param.typ.skipTypes({tyVar, tyLent, tyTypeDesc}).kind notin {
|
||||
tyArray, tyOpenArray, tyVarargs}:
|
||||
|
|
@ -513,7 +555,7 @@ proc genRecordFieldsAux(m: BModule, n: PNode,
|
|||
if fieldType.kind == tyUncheckedArray:
|
||||
addf(result, "$1 $2[SEQ_DECL_SIZE];$n",
|
||||
[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.
|
||||
addf(result, "$1 $2;$n", [getTypeDescWeak(m, field.loc.t, check), sname])
|
||||
elif field.bitsize != 0:
|
||||
|
|
@ -627,15 +669,6 @@ proc resolveStarsInCppType(typ: PType, idx, stars: int): PType =
|
|||
result = if result.kind == tyGenericInst: result.sons[1]
|
||||
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 =
|
||||
# returns only the type's name
|
||||
var t = origTyp.skipTypes(irrelevantForBackend-{tyOwned})
|
||||
|
|
@ -675,11 +708,15 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope =
|
|||
result = name & star
|
||||
m.typeCache[sig] = result
|
||||
of tySequence:
|
||||
# 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)
|
||||
if m.config.selectedGC == gcDestructors:
|
||||
result = getTypeDescWeak(m, et, check) & star
|
||||
m.typeCache[sig] = result
|
||||
else:
|
||||
# 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 we have a strong dependency :-(
|
||||
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",
|
||||
[result, rettype, desc])
|
||||
of tySequence:
|
||||
# we cannot use getTypeForward here because then t would be associated
|
||||
# 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 m.config.selectedGC == gcDestructors:
|
||||
result = getTypeDescWeak(m, t, check)
|
||||
else:
|
||||
# we cannot use getTypeForward here because then t would be associated
|
||||
# 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):
|
||||
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 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 skipTypes(t.sons[0], typedescInst).kind != tyEmpty:
|
||||
const
|
||||
cppSeq = "struct $2 : #TGenericSeq {$n"
|
||||
cSeq = "struct $2 {$n" &
|
||||
" #TGenericSeq Sup;$n"
|
||||
if m.compileToCpp:
|
||||
appcg(m, m.s[cfsSeqTypes],
|
||||
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],
|
||||
cSeq & " $1 data[SEQ_DECL_SIZE];$n" &
|
||||
"};$n", [getTypeDescAux(m, t.sons[0], check), result])
|
||||
elif m.config.selectedGC == gcDestructors:
|
||||
internalError(m.config, "cannot map the empty seq type to a C type")
|
||||
else:
|
||||
result = rope("TGenericSeq")
|
||||
add(result, seqStar(m))
|
||||
else:
|
||||
result = rope("TGenericSeq")
|
||||
add(result, seqStar(m))
|
||||
of tyUncheckedArray:
|
||||
result = getTypeName(m, origTyp, sig)
|
||||
m.typeCache[sig] = result
|
||||
|
|
@ -830,21 +861,8 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope =
|
|||
m.typeCache[sig] = typedefName
|
||||
result = typedefName
|
||||
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)
|
||||
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)
|
||||
m.forwTypeCache[sig] = result
|
||||
if not isImportedType(t):
|
||||
|
|
@ -903,8 +921,13 @@ proc getClosureType(m: BModule, t: PType, kind: TClosureTypeKind): Rope =
|
|||
|
||||
proc finishTypeDescriptions(m: BModule) =
|
||||
var i = 0
|
||||
var check = initIntSet()
|
||||
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)
|
||||
|
||||
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:
|
||||
rawMessage(m.config, errGenerated, "system module needs: " & name)
|
||||
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)
|
||||
|
||||
proc generateHeaders(m: BModule) =
|
||||
|
|
|
|||
|
|
@ -20,5 +20,17 @@ proc 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()
|
||||
discard cprintf("%ld %ld new: %ld\n", a, d, allocs)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue