remerge "allow void as field type"
This commit is contained in:
parent
6ddd4e6a3f
commit
19eeb3556e
2 changed files with 43 additions and 27 deletions
|
|
@ -437,8 +437,9 @@ proc genRecordFieldsAux(m: BModule, n: PNode,
|
||||||
app(result, genRecordFieldsAux(m, k, ae, rectype, check))
|
app(result, genRecordFieldsAux(m, k, ae, rectype, check))
|
||||||
else: internalError("genRecordFieldsAux(record case branch)")
|
else: internalError("genRecordFieldsAux(record case branch)")
|
||||||
appf(result, "} $1;$n", [uname])
|
appf(result, "} $1;$n", [uname])
|
||||||
of nkSym:
|
of nkSym:
|
||||||
field = n.sym
|
field = n.sym
|
||||||
|
if field.typ.kind == tyEmpty: return
|
||||||
#assert(field.ast == nil)
|
#assert(field.ast == nil)
|
||||||
sname = mangleRecFieldName(field, rectype)
|
sname = mangleRecFieldName(field, rectype)
|
||||||
if accessExpr != nil: ae = ropef("$1.$2", [accessExpr, sname])
|
if accessExpr != nil: ae = ropef("$1.$2", [accessExpr, sname])
|
||||||
|
|
|
||||||
|
|
@ -926,11 +926,21 @@ proc commonSuperclass*(a, b: PType): PType =
|
||||||
if ancestors.contains(y.id): return y
|
if ancestors.contains(y.id): return y
|
||||||
y = y.sons[0]
|
y = y.sons[0]
|
||||||
|
|
||||||
proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind): bool
|
type
|
||||||
proc typeAllowedNode(marker: var TIntSet, n: PNode, kind: TSymKind): bool =
|
TTypeAllowedFlag = enum
|
||||||
|
taField,
|
||||||
|
taHeap
|
||||||
|
|
||||||
|
TTypeAllowedFlags = set[TTypeAllowedFlag]
|
||||||
|
|
||||||
|
proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind,
|
||||||
|
flags: TTypeAllowedFlags = {}): bool
|
||||||
|
|
||||||
|
proc typeAllowedNode(marker: var TIntSet, n: PNode, kind: TSymKind,
|
||||||
|
flags: TTypeAllowedFlags = {}): bool =
|
||||||
result = true
|
result = true
|
||||||
if n != nil:
|
if n != nil:
|
||||||
result = typeAllowedAux(marker, n.typ, kind)
|
result = typeAllowedAux(marker, n.typ, kind, flags)
|
||||||
#if not result: debug(n.typ)
|
#if not result: debug(n.typ)
|
||||||
if result:
|
if result:
|
||||||
case n.kind
|
case n.kind
|
||||||
|
|
@ -938,7 +948,7 @@ proc typeAllowedNode(marker: var TIntSet, n: PNode, kind: TSymKind): bool =
|
||||||
nil
|
nil
|
||||||
else:
|
else:
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
result = typeAllowedNode(marker, n.sons[i], kind)
|
result = typeAllowedNode(marker, n.sons[i], kind, flags)
|
||||||
if not result: break
|
if not result: break
|
||||||
|
|
||||||
proc matchType*(a: PType, pattern: openArray[tuple[k:TTypeKind, i:int]],
|
proc matchType*(a: PType, pattern: openArray[tuple[k:TTypeKind, i:int]],
|
||||||
|
|
@ -990,7 +1000,8 @@ proc matchTypeClass*(typeClass, typ: PType): bool =
|
||||||
initIdTable(bindings)
|
initIdTable(bindings)
|
||||||
result = matchTypeClass(bindings, typeClass, typ)
|
result = matchTypeClass(bindings, typeClass, typ)
|
||||||
|
|
||||||
proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind): bool =
|
proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind,
|
||||||
|
flags: TTypeAllowedFlags = {}): bool =
|
||||||
assert(kind in {skVar, skLet, skConst, skParam, skResult})
|
assert(kind in {skVar, skLet, skConst, skParam, skResult})
|
||||||
# if we have already checked the type, return true, because we stop the
|
# if we have already checked the type, return true, because we stop the
|
||||||
# evaluation if something is wrong:
|
# evaluation if something is wrong:
|
||||||
|
|
@ -1004,66 +1015,70 @@ proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind): bool =
|
||||||
var t2 = skipTypes(t.sons[0], abstractInst-{tyTypeDesc})
|
var t2 = skipTypes(t.sons[0], abstractInst-{tyTypeDesc})
|
||||||
case t2.kind
|
case t2.kind
|
||||||
of tyVar:
|
of tyVar:
|
||||||
result = false # ``var var`` is always an invalid type:
|
result = taHeap in flags # ``var var`` is illegal on the heap:
|
||||||
of tyOpenArray:
|
of tyOpenArray:
|
||||||
result = kind == skParam and typeAllowedAux(marker, t2, kind)
|
result = kind == skParam and typeAllowedAux(marker, t2, kind, flags)
|
||||||
else:
|
else:
|
||||||
result = kind in {skParam, skResult} and typeAllowedAux(marker, t2, kind)
|
result = kind in {skParam, skResult} and
|
||||||
|
typeAllowedAux(marker, t2, kind, flags)
|
||||||
of tyProc:
|
of tyProc:
|
||||||
for i in countup(1, sonsLen(t) - 1):
|
for i in countup(1, sonsLen(t) - 1):
|
||||||
result = typeAllowedAux(marker, t.sons[i], skParam)
|
result = typeAllowedAux(marker, t.sons[i], skParam, flags)
|
||||||
if not result: break
|
if not result: break
|
||||||
if result and t.sons[0] != nil:
|
if result and t.sons[0] != nil:
|
||||||
result = typeAllowedAux(marker, t.sons[0], skResult)
|
result = typeAllowedAux(marker, t.sons[0], skResult, flags)
|
||||||
of tyExpr, tyStmt, tyTypeDesc:
|
of tyExpr, tyStmt, tyTypeDesc:
|
||||||
result = true
|
result = true
|
||||||
# XXX er ... no? these should not be allowed!
|
# XXX er ... no? these should not be allowed!
|
||||||
|
of tyEmpty:
|
||||||
|
result = taField in flags
|
||||||
of tyTypeClass:
|
of tyTypeClass:
|
||||||
result = true
|
result = true
|
||||||
of tyGenericBody, tyGenericParam, tyForward, tyNone, tyGenericInvokation:
|
of tyGenericBody, tyGenericParam, tyForward, tyNone, tyGenericInvokation:
|
||||||
result = false
|
result = false
|
||||||
of tyEmpty, tyNil:
|
of tyNil:
|
||||||
result = kind == skConst
|
result = kind == skConst
|
||||||
of tyString, tyBool, tyChar, tyEnum, tyInt..tyBigNum, tyCString, tyPointer:
|
of tyString, tyBool, tyChar, tyEnum, tyInt..tyBigNum, tyCString, tyPointer:
|
||||||
result = true
|
result = true
|
||||||
of tyOrdinal:
|
of tyOrdinal:
|
||||||
result = kind == skParam
|
result = kind == skParam
|
||||||
of tyGenericInst, tyDistinct:
|
of tyGenericInst, tyDistinct:
|
||||||
result = typeAllowedAux(marker, lastSon(t), kind)
|
result = typeAllowedAux(marker, lastSon(t), kind, flags)
|
||||||
of tyRange:
|
of tyRange:
|
||||||
result = skipTypes(t.sons[0], abstractInst-{tyTypeDesc}).kind in
|
result = skipTypes(t.sons[0], abstractInst-{tyTypeDesc}).kind in
|
||||||
{tyChar, tyEnum, tyInt..tyUInt64}
|
{tyChar, tyEnum, tyInt..tyUInt64}
|
||||||
of tyOpenArray, tyVarargs:
|
of tyOpenArray, tyVarargs:
|
||||||
result = (kind == skParam) and typeAllowedAux(marker, t.sons[0], skVar)
|
result = (kind == skParam) and typeAllowedAux(marker, t.sons[0], skVar, flags)
|
||||||
of tySequence:
|
of tySequence:
|
||||||
result = t.sons[0].kind == tyEmpty or
|
result = t.sons[0].kind == tyEmpty or
|
||||||
typeAllowedAux(marker, t.sons[0], skVar)
|
typeAllowedAux(marker, t.sons[0], skVar, flags+{taHeap})
|
||||||
of tyArray:
|
of tyArray:
|
||||||
result = t.sons[1].kind == tyEmpty or
|
result = t.sons[1].kind == tyEmpty or
|
||||||
typeAllowedAux(marker, t.sons[1], skVar)
|
typeAllowedAux(marker, t.sons[1], skVar, flags)
|
||||||
of tyRef:
|
of tyRef:
|
||||||
if kind == skConst: return false
|
if kind == skConst: return false
|
||||||
result = typeAllowedAux(marker, t.sons[0], skVar)
|
result = typeAllowedAux(marker, t.sons[0], skVar, flags+{taHeap})
|
||||||
of tyPtr:
|
of tyPtr:
|
||||||
result = typeAllowedAux(marker, t.sons[0], skVar)
|
result = typeAllowedAux(marker, t.sons[0], skVar, flags+{taHeap})
|
||||||
of tyArrayConstr, tyTuple, tySet, tyConst, tyMutable, tyIter:
|
of tyArrayConstr, tySet, tyConst, tyMutable, tyIter:
|
||||||
for i in countup(0, sonsLen(t) - 1):
|
for i in countup(0, sonsLen(t) - 1):
|
||||||
result = typeAllowedAux(marker, t.sons[i], kind)
|
result = typeAllowedAux(marker, t.sons[i], kind, flags)
|
||||||
if not result: break
|
if not result: break
|
||||||
of tyObject:
|
of tyObject, tyTuple:
|
||||||
if kind == skConst: return false
|
if kind == skConst and t.kind == tyObject: return false
|
||||||
|
let flags = flags+{taField}
|
||||||
for i in countup(0, sonsLen(t) - 1):
|
for i in countup(0, sonsLen(t) - 1):
|
||||||
result = typeAllowedAux(marker, t.sons[i], kind)
|
result = typeAllowedAux(marker, t.sons[i], kind, flags)
|
||||||
if not result: break
|
if not result: break
|
||||||
if result and t.n != nil: result = typeAllowedNode(marker, t.n, kind)
|
if result and t.n != nil: result = typeAllowedNode(marker, t.n, kind, flags)
|
||||||
of tyProxy:
|
of tyProxy:
|
||||||
# for now same as error node; we say it's a valid type as it should
|
# for now same as error node; we say it's a valid type as it should
|
||||||
# prevent cascading errors:
|
# prevent cascading errors:
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
proc typeAllowed(t: PType, kind: TSymKind): bool =
|
proc typeAllowed(t: PType, kind: TSymKind): bool =
|
||||||
var marker = InitIntSet()
|
var marker = InitIntSet()
|
||||||
result = typeAllowedAux(marker, t, kind)
|
result = typeAllowedAux(marker, t, kind, {})
|
||||||
|
|
||||||
proc align(address, alignment: biggestInt): biggestInt =
|
proc align(address, alignment: biggestInt): biggestInt =
|
||||||
result = (address + (alignment - 1)) and not (alignment - 1)
|
result = (address + (alignment - 1)) and not (alignment - 1)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue