beginning of a taint mode; type system enhancements

This commit is contained in:
Araq 2011-09-24 00:46:41 +02:00
commit 6023e994fb
18 changed files with 265 additions and 283 deletions

View file

@ -143,6 +143,7 @@ type
nkWhileStmt, # a while statement
nkCaseStmt, # a case statement
nkVarSection, # a var section
nkLetSection, # a let section
nkConstSection, # a const section
nkConstDef, # a const definition
nkTypeSection, # a type section (consists of type definitions)
@ -178,6 +179,8 @@ type
nkRefTy,
nkPtrTy,
nkVarTy,
nkConstTy, # ``const T``
nkMutableTy, # ``mutable T``
nkDistinctTy, # distinct type
nkProcTy,
nkEnumTy,
@ -186,7 +189,7 @@ type
TNodeKinds* = set[TNodeKind]
type
TSymFlag* = enum # already 29 flags!
TSymFlag* = enum # already 30 flags!
sfUsed, # read access of sym (for warnings) or simply used
sfExported, # symbol is exported from module
sfFromGeneric, # symbol is instantiation of a generic; this is needed
@ -212,6 +215,7 @@ type
sfProcvar, # proc can be passed to a proc var
sfDiscriminant, # field is a discriminant in a record/object
sfDeprecated, # symbol is deprecated
sfError, # usage of symbol should trigger a compile-time error
sfInClosure, # variable is accessed by a closure
sfThread, # proc will run as a thread
sfCompileTime, # proc can be evaluated at compile time
@ -254,7 +258,12 @@ type
tyPointer, tyOpenArray,
tyString, tyCString, tyForward,
tyInt, tyInt8, tyInt16, tyInt32, tyInt64, # signed integers
tyFloat, tyFloat32, tyFloat64, tyFloat128
tyFloat, tyFloat32, tyFloat64, tyFloat128,
tyUInt, tyUInt8, tyUInt16, tyUInt32, tyUInt64,
tyBigNum,
tyConst, tyMutable, tyVarargs,
tyIter, # unused
tyProxy # currently unused
TTypeKinds* = set[TTypeKind]

View file

@ -30,94 +30,8 @@ const
"Copyright (c) 2004-2011 by Andreas Rumpf\n"
const
Usage = """
Usage:
nimrod command [options] [projectfile] [arguments]
Command:
compile, c compile project with default code generator (C)
doc generate the documentation for inputfile
i start Nimrod in interactive mode (limited)
Arguments:
arguments are passed to the program being run (if --run option is selected)
Options:
-p, --path:PATH add path to search paths
-d, --define:SYMBOL define a conditional symbol
-u, --undef:SYMBOL undefine a conditional symbol
-f, --forceBuild force rebuilding of all modules
--stackTrace:on|off turn stack tracing on|off
--lineTrace:on|off turn line tracing on|off
--threads:on|off turn support for multi-threading on|off
-x, --checks:on|off turn all runtime checks on|off
--objChecks:on|off turn obj conversion checks on|off
--fieldChecks:on|off turn case variant field checks on|off
--rangeChecks:on|off turn range checks on|off
--boundChecks:on|off turn bound checks on|off
--overflowChecks:on|off turn int over-/underflow checks on|off
-a, --assertions:on|off turn assertions on|off
--floatChecks:on|off turn all floating point (NaN/Inf) checks on|off
--nanChecks:on|off turn NaN checks on|off
--infChecks:on|off turn Inf checks on|off
--deadCodeElim:on|off whole program dead code elimination on|off
--opt:none|speed|size optimize not at all or for speed|size
--app:console|gui|lib generate a console|GUI application|dynamic library
-r, --run run the compiled program with given arguments
--advanced show advanced command line switches
-h, --help show this help
"""
AdvancedUsage = """
Advanced commands:
compileToC, cc compile project with C code generator
compileToCpp, cpp compile project to C++ code
compileToOC, objc compile project to Objective C code
rst2html convert a reStructuredText file to HTML
rst2tex convert a reStructuredText file to TeX
run run the project (with Tiny C backend; buggy!)
pretty pretty print the inputfile
genDepend generate a DOT file containing the
module dependency graph
dump dump all defined conditionals and search paths
check checks the project for syntax and semantic
idetools compiler support for IDEs: possible options:
--track:FILE,LINE,COL track a file/cursor position
--suggest suggest all possible symbols at position
--def list all possible symbols at position
--context list possible invokation context
Advanced options:
-o, --out:FILE set the output filename
--stdout output to stdout
-w, --warnings:on|off turn all warnings on|off
--warning[X]:on|off turn specific warning X on|off
--hints:on|off turn all hints on|off
--hint[X]:on|off turn specific hint X on|off
--lib:PATH set the system library path
--nimcache:PATH set the path used for generated files
-c, --compileOnly compile only; do not assemble or link
--noLinking compile but do not link
--noMain do not generate a main procedure
--genScript generate a compile script (in the 'nimcache'
subdirectory named 'compile_$project$scriptext')
--os:SYMBOL set the target operating system (cross-compilation)
--cpu:SYMBOL set the target processor (cross-compilation)
--debuginfo enables debug information
--debugger:on|off turn Embedded Nimrod Debugger on|off
-t, --passc:OPTION pass an option to the C compiler
-l, --passl:OPTION pass an option to the linker
--genMapping generate a mapping file containing
(Nimrod, mangled) identifier pairs
--lineDir:on|off generation of #line directive on|off
--threadanalysis:on|off turn thread analysis on|off
--skipCfg do not read the general configuration file
--skipProjCfg do not read the project's configuration file
--gc:refc|boehm|none use Nimrod's native GC|Boehm GC|no GC
--index:FILE use FILE to generate a documentation index file
--putenv:key=value set an environment variable
--listCmd list the commands used to execute external programs
--parallelBuild=0|1|... perform a parallel build
value = number of processors (0 for auto-detect)
--verbosity:0|1|2|3 set Nimrod's verbosity level (0 is default)
-v, --version show detailed version information
"""
Usage = slurp"doc/basicopt.txt".replace("//", "")
AdvancedUsage = slurp"doc/advopt.txt".replace("//", "")
proc getCommandLineDesc(): string =
result = `%`(HelpMessage, [VersionAsString, platform.os[platform.hostOS].name,
@ -276,6 +190,7 @@ proc testCompileOption*(switch: string, info: TLineInfo): bool =
of "symbolfiles": result = contains(gGlobalOptions, optSymbolFiles)
of "genscript": result = contains(gGlobalOptions, optGenScript)
of "threads": result = contains(gGlobalOptions, optThreads)
of "taintmode": result = contains(gGlobalOptions, optTaintMode)
else: InvalidCmdLineOption(passCmd1, switch, info)
proc processPath(path: string): string =
@ -399,6 +314,7 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) =
of "assertions", "a": ProcessOnOffSwitch({optAssert}, arg, pass, info)
of "deadcodeelim": ProcessOnOffSwitchG({optDeadCodeElim}, arg, pass, info)
of "threads": ProcessOnOffSwitchG({optThreads}, arg, pass, info)
of "taintmode": ProcessOnOffSwitchG({optTaintMode}, arg, pass, info)
of "opt":
expectArg(switch, arg, pass, info)
case arg.normalize

View file

@ -89,7 +89,7 @@ type
errCannotInterpretNodeX, errFieldXNotFound, errInvalidConversionFromTypeX,
errAssertionFailed, errCannotGenerateCodeForX, errXRequiresOneArgument,
errUnhandledExceptionX, errCyclicTree, errXisNoMacroOrTemplate,
errXhasSideEffects, errIteratorExpected,
errXhasSideEffects, errIteratorExpected, errWrongSymbolX,
errUser,
warnCannotOpenFile,
warnOctalEscape, warnXIsNeverRead, warnXmightNotBeenInit,
@ -315,6 +315,7 @@ const
errXisNoMacroOrTemplate: "\'$1\' is no macro or template",
errXhasSideEffects: "\'$1\' can have side effects",
errIteratorExpected: "iterator within for loop context expected",
errWrongSymbolX: "usage of \'$1\' is a user-defined error",
errUser: "$1",
warnCannotOpenFile: "cannot open \'$1\' [CannotOpenFile]",
warnOctalEscape: "octal escape sequences do not exist; leading zero is ignored [OctalEscape]",

View file

@ -46,7 +46,8 @@ type # please make sure we have under 32 options
optSuggest, # ideTools: 'suggest'
optContext, # ideTools: 'context'
optDef, # ideTools: 'def'
optThreadAnalysis # thread analysis pass
optThreadAnalysis, # thread analysis pass
optTaintMode # taint mode turned on
TGlobalOptions* = set[TGlobalOption]
TCommands* = enum # Nimrod's commands

View file

@ -23,15 +23,15 @@ const
wMagic, wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader,
wCompilerProc, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge,
wBorrow, wExtern, wImportCompilerProc, wThread, wImportCpp, wImportObjC,
wNoStackFrame}
wNoStackFrame, wError}
converterPragmas* = procPragmas
methodPragmas* = procPragmas
macroPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl,
wMagic, wNosideEffect, wCompilerProc, wDeprecated, wExtern,
wImportcpp, wImportobjc}
wImportcpp, wImportobjc, wError}
iteratorPragmas* = {FirstCallConv..LastCallConv, wNosideEffect, wSideEffect,
wImportc, wExportc, wNodecl, wMagic, wDeprecated, wBorrow, wExtern,
wImportcpp, wImportobjc}
wImportcpp, wImportobjc, wError}
stmtPragmas* = {wChecks, wObjChecks, wFieldChecks, wRangechecks, wBoundchecks,
wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints, wLinedir,
wStacktrace, wLinetrace, wOptimization, wHint, wWarning, wError, wFatal,
@ -43,14 +43,14 @@ const
wDeprecated, wExtern, wThread, wImportcpp, wImportobjc, wNoStackFrame}
typePragmas* = {wImportc, wExportc, wDeprecated, wMagic, wAcyclic, wNodecl,
wPure, wHeader, wCompilerProc, wFinal, wSize, wExtern, wShallow,
wImportcpp, wImportobjc}
wImportcpp, wImportobjc, wError}
fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern,
wImportcpp, wImportobjc}
wImportcpp, wImportobjc, wError}
varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl,
wMagic, wHeader, wDeprecated, wCompilerProc, wDynLib, wExtern,
wImportcpp, wImportobjc}
wImportcpp, wImportobjc, wError}
constPragmas* = {wImportc, wExportc, wHeader, wDeprecated, wMagic, wNodecl,
wExtern, wImportcpp, wImportobjc}
wExtern, wImportcpp, wImportobjc, wError}
procTypePragmas* = {FirstCallConv..LastCallConv, wVarargs, wNosideEffect,
wThread}
allRoutinePragmas* = procPragmas + iteratorPragmas + lambdaPragmas
@ -530,7 +530,12 @@ proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
if sym.typ != nil: incl(sym.typ.flags, tfThread)
of wHint: Message(it.info, hintUser, expectStrLit(c, it))
of wWarning: Message(it.info, warnUser, expectStrLit(c, it))
of wError: LocalError(it.info, errUser, expectStrLit(c, it))
of wError:
if sym != nil:
noVal(it)
incl(sym.flags, sfError)
else:
LocalError(it.info, errUser, expectStrLit(c, it))
of wFatal: Fatal(it.info, errUser, expectStrLit(c, it))
of wDefine: processDefine(c, it)
of wUndef: processUndef(c, it)

View file

@ -178,7 +178,9 @@ proc makeRangeType(c: PContext, first, last: biggestInt,
proc markUsed*(n: PNode, s: PSym) =
incl(s.flags, sfUsed)
if sfDeprecated in s.flags: Message(n.info, warnDeprecated, s.name.s)
if {sfDeprecated, sfError} * s.flags != {}:
if sfDeprecated in s.flags: Message(n.info, warnDeprecated, s.name.s)
if sfError in s.flags: LocalError(n.info, errWrongSymbolX, s.name.s)
proc illFormedAst*(n: PNode) =
GlobalError(n.info, errIllFormedAstX, renderTree(n, {renderNoComments}))

View file

@ -103,7 +103,7 @@ proc checkConversionBetweenObjects(info: TLineInfo, castDest, src: PType) =
proc checkConvertible(info: TLineInfo, castDest, src: PType) =
const
IntegralTypes = {tyBool, tyEnum, tyChar, tyInt..tyFloat128}
if sameType(castDest, src):
if sameType(castDest, src) and castDest.sym == src.sym:
# don't annoy conversions that may be needed on another processor:
if not (castDest.kind in {tyInt..tyFloat128, tyNil}):
Message(info, hintConvFromXtoItselfNotNeeded, typeToString(castDest))

View file

@ -50,16 +50,19 @@ proc equalParams*(a, b: PNode): TParamsEquality
proc isOrdinalType*(t: PType): bool
proc enumHasHoles*(t: PType): bool
const
abstractPtrs* = {tyVar, tyPtr, tyRef, tyGenericInst, tyDistinct, tyOrdinal}
abstractVar* = {tyVar, tyGenericInst, tyDistinct, tyOrdinal}
abstractRange* = {tyGenericInst, tyRange, tyDistinct, tyOrdinal}
abstractVarRange* = {tyGenericInst, tyRange, tyVar, tyDistinct, tyOrdinal}
abstractInst* = {tyGenericInst, tyDistinct, tyOrdinal}
abstractPtrs* = {tyVar, tyPtr, tyRef, tyGenericInst, tyDistinct, tyOrdinal,
tyConst, tyMutable}
abstractVar* = {tyVar, tyGenericInst, tyDistinct, tyOrdinal,
tyConst, tyMutable}
abstractRange* = {tyGenericInst, tyRange, tyDistinct, tyOrdinal,
tyConst, tyMutable}
abstractVarRange* = {tyGenericInst, tyRange, tyVar, tyDistinct, tyOrdinal,
tyConst, tyMutable}
abstractInst* = {tyGenericInst, tyDistinct, tyOrdinal, tyConst, tyMutable}
skipPtrs* = {tyVar, tyPtr, tyRef, tyGenericInst}
skipPtrs* = {tyVar, tyPtr, tyRef, tyGenericInst, tyConst, tyMutable}
proc skipTypes*(t: PType, kinds: TTypeKinds): PType
proc elemType*(t: PType): PType
proc containsObject*(t: PType): bool
proc containsGarbageCollectedRef*(typ: PType): bool
proc containsHiddenPointer*(typ: PType): bool
@ -122,10 +125,11 @@ proc getOrdValue(n: PNode): biggestInt =
result = 0
proc isCompatibleToCString(a: PType): bool =
result = false
if a.kind == tyArray:
if (firstOrd(a.sons[0]) == 0) and
(skipTypes(a.sons[0], {tyRange}).kind in {tyInt..tyInt64}) and
(skipTypes(a.sons[0], {tyRange, tyConst,
tyMutable, tyGenericInst}).kind in
{tyInt..tyInt64, tyUInt..tyUInt64}) and
(a.sons[1].kind == tyChar):
result = true
@ -142,7 +146,7 @@ proc getProcHeader(sym: PSym): string =
add(result, ')')
if n.sons[0].typ != nil: result.add(": " & typeToString(n.sons[0].typ))
proc elemType(t: PType): PType =
proc elemType*(t: PType): PType =
assert(t != nil)
case t.kind
of tyGenericInst, tyDistinct: result = elemType(lastSon(t))
@ -153,36 +157,7 @@ proc elemType(t: PType): PType =
proc skipGeneric(t: PType): PType =
result = t
while result.kind == tyGenericInst: result = lastSon(result)
proc skipRange(t: PType): PType =
result = t
while result.kind == tyRange: result = base(result)
proc skipAbstract(t: PType): PType =
result = t
while result.kind in {tyRange, tyGenericInst}: result = lastSon(result)
proc skipVar(t: PType): PType =
result = t
while result.kind == tyVar: result = result.sons[0]
proc skipVarGeneric(t: PType): PType =
result = t
while result.kind in {tyGenericInst, tyVar}: result = lastSon(result)
proc skipPtrsGeneric(t: PType): PType =
result = t
while result.kind in {tyGenericInst, tyVar, tyPtr, tyRef}:
result = lastSon(result)
proc skipVarGenericRange(t: PType): PType =
result = t
while result.kind in {tyGenericInst, tyVar, tyRange}: result = lastSon(result)
proc skipGenericRange(t: PType): PType =
result = t
while result.kind in {tyGenericInst, tyVar, tyRange}: result = lastSon(result)
proc skipTypes(t: PType, kinds: TTypeKinds): PType =
result = t
while result.kind in kinds: result = lastSon(result)
@ -190,18 +165,18 @@ proc skipTypes(t: PType, kinds: TTypeKinds): PType =
proc isOrdinalType(t: PType): bool =
assert(t != nil)
result = (t.Kind in {tyChar, tyInt..tyInt64, tyBool, tyEnum}) or
(t.Kind in {tyRange, tyOrdinal}) and isOrdinalType(t.sons[0])
(t.Kind in {tyRange, tyOrdinal, tyConst, tyMutable, tyGenericInst}) and
isOrdinalType(t.sons[0])
proc enumHasHoles(t: PType): bool =
var b = t
while b.kind == tyRange: b = b.sons[0]
while b.kind in {tyConst, tyMutable, tyRange, tyGenericInst}: b = b.sons[0]
result = b.Kind == tyEnum and tfEnumHasHoles in b.flags
proc iterOverTypeAux(marker: var TIntSet, t: PType, iter: TTypeIter,
closure: PObject): bool
proc iterOverNode(marker: var TIntSet, n: PNode, iter: TTypeIter,
closure: PObject): bool =
result = false
if n != nil:
case n.kind
of nkNone..nkNilLit:
@ -289,9 +264,9 @@ proc containsObject(t: PType): bool =
result = searchTypeFor(t, isObjectPredicate)
proc isObjectWithTypeFieldPredicate(t: PType): bool =
result = (t.kind == tyObject) and (t.sons[0] == nil) and
not ((t.sym != nil) and (sfPure in t.sym.flags)) and
not (tfFinal in t.flags)
result = t.kind == tyObject and t.sons[0] == nil and
not (t.sym != nil and sfPure in t.sym.flags) and
tfFinal notin t.flags
proc analyseObjectWithTypeFieldAux(t: PType,
marker: var TIntSet): TTypeFieldResult =
@ -310,7 +285,7 @@ proc analyseObjectWithTypeFieldAux(t: PType,
if res == frHeader: result = frHeader
if result == frNone:
if isObjectWithTypeFieldPredicate(t): result = frHeader
of tyGenericInst, tyDistinct:
of tyGenericInst, tyDistinct, tyConst, tyMutable:
result = analyseObjectWithTypeFieldAux(lastSon(t), marker)
of tyArray, tyArrayConstr, tyTuple:
for i in countup(0, sonsLen(t) - 1):
@ -406,8 +381,6 @@ proc mutateTypeAux(marker: var TIntSet, t: PType, iter: TTypeMutator,
if not ContainsOrIncl(marker, t.id):
for i in countup(0, sonsLen(t) - 1):
result.sons[i] = mutateTypeAux(marker, result.sons[i], iter, closure)
if (result.sons[i] == nil) and (result.kind == tyGenericInst):
assert(false)
if t.n != nil: result.n = mutateNode(marker, t.n, iter, closure)
assert(result != nil)
@ -427,7 +400,10 @@ proc TypeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
"distinct $1", "enum", "ordinal[$1]", "array[$1, $2]", "object", "tuple",
"set[$1]", "range[$1]", "ptr ", "ref ", "var ", "seq[$1]", "proc",
"pointer", "OpenArray[$1]", "string", "CString", "Forward", "int", "int8",
"int16", "int32", "int64", "float", "float32", "float64", "float128"]
"int16", "int32", "int64", "float", "float32", "float64", "float128",
"uint", "uint8", "uint16", "uint32", "uint64", "bignum", "const ",
"!", "varargs[$1]", "iter[$1]", "proxy[$1]"]
var t = typ
result = ""
if t == nil: return
@ -474,7 +450,7 @@ proc TypeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
add(result, typeToString(t.sons[i]))
if i < sonsLen(t) - 1: add(result, ", ")
add(result, ']')
of tyPtr, tyRef, tyVar:
of tyPtr, tyRef, tyVar, tyMutable, tyConst:
result = typeToStr[t.kind] & typeToString(t.sons[0])
of tyRange:
result = "range " & rangeToStr(t.n)
@ -495,6 +471,8 @@ proc TypeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
addSep(prag)
add(prag, "thread")
if len(prag) != 0: add(result, "{." & prag & ".}")
of tyVarargs, tyIter, tyProxy:
result = typeToStr[t.kind] % typeToString(t.sons[0])
else:
result = typeToStr[t.kind]
@ -528,7 +506,8 @@ proc firstOrd(t: PType): biggestInt =
else:
assert(t.n.sons[0].kind == nkSym)
result = t.n.sons[0].sym.position
of tyGenericInst, tyDistinct: result = firstOrd(lastSon(t))
of tyGenericInst, tyDistinct, tyConst, tyMutable:
result = firstOrd(lastSon(t))
else:
InternalError("invalid kind for first(" & $t.kind & ')')
result = 0
@ -553,7 +532,8 @@ proc lastOrd(t: PType): biggestInt =
of tyEnum:
assert(t.n.sons[sonsLen(t.n) - 1].kind == nkSym)
result = t.n.sons[sonsLen(t.n) - 1].sym.position
of tyGenericInst, tyDistinct: result = lastOrd(lastSon(t))
of tyGenericInst, tyDistinct, tyConst, tyMutable:
result = lastOrd(lastSon(t))
else:
InternalError("invalid kind for last(" & $t.kind & ')')
result = 0
@ -561,21 +541,21 @@ proc lastOrd(t: PType): biggestInt =
proc lengthOrd(t: PType): biggestInt =
case t.kind
of tyInt64, tyInt32, tyInt: result = lastOrd(t)
of tyDistinct: result = lengthOrd(t.sons[0])
of tyDistinct, tyConst, tyMutable: result = lengthOrd(t.sons[0])
else: result = lastOrd(t) - firstOrd(t) + 1
proc equalParam(a, b: PSym): TParamsEquality =
if SameTypeOrNil(a.typ, b.typ):
if (a.ast == b.ast):
if a.ast == b.ast:
result = paramsEqual
elif (a.ast != nil) and (b.ast != nil):
elif a.ast != nil and b.ast != nil:
if ExprStructuralEquivalent(a.ast, b.ast): result = paramsEqual
else: result = paramsIncompatible
elif (a.ast != nil):
elif a.ast != nil:
result = paramsEqual
elif (b.ast != nil):
elif b.ast != nil:
result = paramsIncompatible
else:
else:
result = paramsNotEqual
proc equalParams(a, b: PNode): TParamsEquality =
@ -611,11 +591,10 @@ proc SameTypeOrNil(a, b: PType): bool =
if a == b:
result = true
else:
if (a == nil) or (b == nil): result = false
if a == nil or b == nil: result = false
else: result = SameType(a, b)
proc SameLiteral(x, y: PNode): bool =
result = false
if x.kind == y.kind:
case x.kind
of nkCharLit..nkInt64Lit: result = x.intVal == y.intVal
@ -625,7 +604,7 @@ proc SameLiteral(x, y: PNode): bool =
proc SameRanges(a, b: PNode): bool =
result = SameLiteral(a.sons[0], b.sons[0]) and
SameLiteral(a.sons[1], b.sons[1])
SameLiteral(a.sons[1], b.sons[1])
proc sameTuple(a, b: PType, DistinctOf: bool): bool =
# two tuples are equivalent iff the names, types and positions are the same;
@ -637,7 +616,7 @@ proc sameTuple(a, b: PType, DistinctOf: bool): bool =
if DistinctOf: result = equalOrDistinctOf(a.sons[i], b.sons[i])
else: result = SameType(a.sons[i], b.sons[i])
if not result: return
if (a.n != nil) and (b.n != nil):
if a.n != nil and b.n != nil:
for i in countup(0, sonsLen(a.n) - 1):
# check field names:
if a.n.sons[i].kind != nkSym: InternalError(a.n.info, "sameTuple")
@ -659,13 +638,14 @@ proc SameType(x, y: PType): bool =
return false
case a.Kind
of tyEmpty, tyChar, tyBool, tyNil, tyPointer, tyString, tyCString,
tyInt..tyFloat128, tyExpr, tyStmt, tyTypeDesc:
tyInt..tyBigNum, tyExpr, tyStmt, tyTypeDesc:
result = true
of tyEnum, tyForward, tyObject, tyDistinct: result = (a.id == b.id)
of tyEnum, tyForward, tyObject, tyDistinct, tyProxy: result = (a.id == b.id)
of tyTuple: result = sameTuple(a, b, false)
of tyGenericInst: result = sameType(lastSon(a), lastSon(b))
of tyGenericParam, tyGenericInvokation, tyGenericBody, tySequence, tyOrdinal,
tyOpenArray, tySet, tyRef, tyPtr, tyVar, tyArrayConstr, tyArray, tyProc:
tyOpenArray, tySet, tyRef, tyPtr, tyVar, tyArrayConstr, tyArray, tyProc,
tyConst, tyMutable, tyVarargs, tyIter:
if sonsLen(a) == sonsLen(b):
result = true
for i in countup(0, sonsLen(a) - 1):
@ -694,13 +674,14 @@ proc equalOrDistinctOf(x, y: PType): bool =
return false
case a.Kind
of tyEmpty, tyChar, tyBool, tyNil, tyPointer, tyString, tyCString,
tyInt..tyFloat128, tyExpr, tyStmt, tyTypeDesc:
tyInt..tyBigNum, tyExpr, tyStmt, tyTypeDesc:
result = true
of tyEnum, tyForward, tyObject, tyDistinct: result = (a.id == b.id)
of tyEnum, tyForward, tyObject, tyDistinct, tyProxy: result = (a.id == b.id)
of tyTuple: result = sameTuple(a, b, true)
of tyGenericInst: result = equalOrDistinctOf(lastSon(a), lastSon(b))
of tyGenericParam, tyGenericInvokation, tyGenericBody, tySequence, tyOrdinal,
tyOpenArray, tySet, tyRef, tyPtr, tyVar, tyArrayConstr, tyArray, tyProc:
tyOpenArray, tySet, tyRef, tyPtr, tyVar, tyArrayConstr, tyArray, tyProc,
tyConst, tyMutable, tyVarargs, tyIter:
if sonsLen(a) == sonsLen(b):
result = true
for i in countup(0, sonsLen(a) - 1):
@ -769,7 +750,7 @@ proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind): bool =
result = false #InternalError('shit found');
of tyEmpty, tyNil:
result = kind == skConst
of tyString, tyBool, tyChar, tyEnum, tyInt..tyFloat128, tyCString, tyPointer:
of tyString, tyBool, tyChar, tyEnum, tyInt..tyBigNum, tyCString, tyPointer:
result = true
of tyOrdinal:
result = kind == skParam
@ -778,7 +759,7 @@ proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind): bool =
of tyRange:
result = skipTypes(t.sons[0], abstractInst).kind in
{tyChar, tyEnum, tyInt..tyFloat128}
of tyOpenArray:
of tyOpenArray, tyVarargs:
result = (kind == skParam) and typeAllowedAux(marker, t.sons[0], skVar)
of tySequence:
result = (kind != skConst) and typeAllowedAux(marker, t.sons[0], skVar) or
@ -788,7 +769,7 @@ proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind): bool =
t.sons[1].kind == tyEmpty
of tyPtr, tyRef:
result = typeAllowedAux(marker, t.sons[0], skVar)
of tyArrayConstr, tyTuple, tySet:
of tyArrayConstr, tyTuple, tySet, tyConst, tyMutable, tyIter, tyProxy:
for i in countup(0, sonsLen(t) - 1):
result = typeAllowedAux(marker, t.sons[i], kind)
if not result: break
@ -856,19 +837,19 @@ proc computeSizeAux(typ: PType, a: var biggestInt): biggestInt =
return
typ.size = - 2 # mark as being computed
case typ.kind
of tyInt:
of tyInt, tyUInt:
result = IntSize
a = result
of tyInt8, tyBool, tyChar:
of tyInt8, tyUInt8, tyBool, tyChar:
result = 1
a = result
of tyInt16:
of tyInt16, tyUInt16:
result = 2
a = result
of tyInt32, tyFloat32:
of tyInt32, tyUInt32, tyFloat32:
result = 4
a = result
of tyInt64, tyFloat64:
of tyInt64, tyUInt64, tyFloat64:
result = 8
a = result
of tyFloat:
@ -878,7 +859,8 @@ proc computeSizeAux(typ: PType, a: var biggestInt): biggestInt =
if typ.callConv == ccClosure: result = 2 * ptrSize
else: result = ptrSize
a = ptrSize
of tyNil, tyCString, tyString, tySequence, tyPtr, tyRef, tyVar, tyOpenArray:
of tyNil, tyCString, tyString, tySequence, tyPtr, tyRef, tyVar, tyOpenArray,
tyBigNum:
result = ptrSize
a = result
of tyArray, tyArrayConstr:
@ -930,7 +912,8 @@ proc computeSizeAux(typ: PType, a: var biggestInt): biggestInt =
if result < 0: return
if a < maxAlign: a = maxAlign
result = align(result, a)
of tyGenericInst, tyDistinct, tyGenericBody:
of tyGenericInst, tyDistinct, tyGenericBody, tyMutable, tyConst, tyIter,
tyProxy:
result = computeSizeAux(lastSon(typ), a)
else:
#internalError("computeSizeAux()")