pragmas compiles again

This commit is contained in:
Andreas Rumpf 2018-05-11 18:53:18 +02:00
commit bb8c47b496
5 changed files with 272 additions and 269 deletions

View file

@ -11,9 +11,9 @@
import import
intsets, options, ast, astalgo, msgs, idents, renderer, types, magicsys, intsets, options, ast, astalgo, msgs, idents, renderer, types, magicsys,
sempass2, strutils, modulegraphs sempass2, strutils, modulegraphs, configuration
proc genConv(n: PNode, d: PType, downcast: bool): PNode = proc genConv(n: PNode, d: PType, downcast: bool; conf: ConfigRef): PNode =
var dest = skipTypes(d, abstractPtrs) var dest = skipTypes(d, abstractPtrs)
var source = skipTypes(n.typ, abstractPtrs) var source = skipTypes(n.typ, abstractPtrs)
if (source.kind == tyObject) and (dest.kind == tyObject): if (source.kind == tyObject) and (dest.kind == tyObject):
@ -24,12 +24,12 @@ proc genConv(n: PNode, d: PType, downcast: bool): PNode =
elif diff < 0: elif diff < 0:
result = newNodeIT(nkObjUpConv, n.info, d) result = newNodeIT(nkObjUpConv, n.info, d)
addSon(result, n) addSon(result, n)
if downcast: internalError(n.info, "cgmeth.genConv: no upcast allowed") if downcast: internalError(conf, n.info, "cgmeth.genConv: no upcast allowed")
elif diff > 0: elif diff > 0:
result = newNodeIT(nkObjDownConv, n.info, d) result = newNodeIT(nkObjDownConv, n.info, d)
addSon(result, n) addSon(result, n)
if not downcast: if not downcast:
internalError(n.info, "cgmeth.genConv: no downcast allowed") internalError(conf, n.info, "cgmeth.genConv: no downcast allowed")
else: else:
result = n result = n
else: else:
@ -42,7 +42,7 @@ proc getDispatcher*(s: PSym): PSym =
let disp = dispn.sym let disp = dispn.sym
if sfDispatcher in disp.flags: result = disp if sfDispatcher in disp.flags: result = disp
proc methodCall*(n: PNode): PNode = proc methodCall*(n: PNode; conf: ConfigRef): PNode =
result = n result = n
# replace ordinary method by dispatcher method: # replace ordinary method by dispatcher method:
let disp = getDispatcher(result.sons[0].sym) let disp = getDispatcher(result.sons[0].sym)
@ -50,9 +50,9 @@ proc methodCall*(n: PNode): PNode =
result.sons[0].sym = disp result.sons[0].sym = disp
# change the arguments to up/downcasts to fit the dispatcher's parameters: # change the arguments to up/downcasts to fit the dispatcher's parameters:
for i in countup(1, sonsLen(result)-1): for i in countup(1, sonsLen(result)-1):
result.sons[i] = genConv(result.sons[i], disp.typ.sons[i], true) result.sons[i] = genConv(result.sons[i], disp.typ.sons[i], true, conf)
else: else:
localError(n.info, "'" & $result.sons[0] & "' lacks a dispatcher") localError(conf, n.info, "'" & $result.sons[0] & "' lacks a dispatcher")
type type
MethodResult = enum No, Invalid, Yes MethodResult = enum No, Invalid, Yes
@ -130,7 +130,7 @@ proc createDispatcher(s: PSym): PSym =
attachDispatcher(disp, newSymNode(disp)) attachDispatcher(disp, newSymNode(disp))
return disp return disp
proc fixupDispatcher(meth, disp: PSym) = proc fixupDispatcher(meth, disp: PSym; conf: ConfigRef) =
# We may have constructed the dispatcher from a method prototype # We may have constructed the dispatcher from a method prototype
# and need to augment the incomplete dispatcher with information # and need to augment the incomplete dispatcher with information
# from later definitions, particularly the resultPos slot. Also, # from later definitions, particularly the resultPos slot. Also,
@ -149,7 +149,7 @@ proc fixupDispatcher(meth, disp: PSym) =
disp.typ.lockLevel = meth.typ.lockLevel disp.typ.lockLevel = meth.typ.lockLevel
elif meth.typ.lockLevel != UnspecifiedLockLevel and elif meth.typ.lockLevel != UnspecifiedLockLevel and
meth.typ.lockLevel != disp.typ.lockLevel: meth.typ.lockLevel != disp.typ.lockLevel:
message(meth.info, warnLockLevel, message(conf, meth.info, warnLockLevel,
"method has lock level $1, but another method has $2" % "method has lock level $1, but another method has $2" %
[$meth.typ.lockLevel, $disp.typ.lockLevel]) [$meth.typ.lockLevel, $disp.typ.lockLevel])
# XXX The following code silences a duplicate warning in # XXX The following code silences a duplicate warning in
@ -166,13 +166,13 @@ proc methodDef*(g: ModuleGraph; s: PSym, fromCache: bool) =
of Yes: of Yes:
add(g.methods[i].methods, s) add(g.methods[i].methods, s)
attachDispatcher(s, lastSon(disp.ast)) attachDispatcher(s, lastSon(disp.ast))
fixupDispatcher(s, disp) fixupDispatcher(s, disp, g.config)
#echo "fixup ", disp.name.s, " ", disp.id #echo "fixup ", disp.name.s, " ", disp.id
when useEffectSystem: checkMethodEffects(disp, s) when useEffectSystem: checkMethodEffects(g, disp, s)
if {sfBase, sfFromGeneric} * s.flags == {sfBase} and if {sfBase, sfFromGeneric} * s.flags == {sfBase} and
g.methods[i].methods[0] != s: g.methods[i].methods[0] != s:
# already exists due to forwarding definition? # already exists due to forwarding definition?
localError(s.info, "method is not a base") localError(g.config, s.info, "method is not a base")
return return
of No: discard of No: discard
of Invalid: of Invalid:
@ -183,10 +183,10 @@ proc methodDef*(g: ModuleGraph; s: PSym, fromCache: bool) =
#if fromCache: #if fromCache:
# internalError(s.info, "no method dispatcher found") # internalError(s.info, "no method dispatcher found")
if witness != nil: if witness != nil:
localError(s.info, "invalid declaration order; cannot attach '" & s.name.s & localError(g.config, s.info, "invalid declaration order; cannot attach '" & s.name.s &
"' to method defined here: " & $witness.info) "' to method defined here: " & $witness.info)
elif sfBase notin s.flags: elif sfBase notin s.flags:
message(s.info, warnUseBase) message(g.config, s.info, warnUseBase)
proc relevantCol(methods: TSymSeq, col: int): bool = proc relevantCol(methods: TSymSeq, col: int): bool =
# returns true iff the position is relevant # returns true iff the position is relevant
@ -225,32 +225,33 @@ proc sortBucket(a: var TSymSeq, relevantCols: IntSet) =
a[j] = v a[j] = v
if h == 1: break if h == 1: break
proc genDispatcher(methods: TSymSeq, relevantCols: IntSet): PSym = proc genDispatcher(g: ModuleGraph; methods: TSymSeq, relevantCols: IntSet): PSym =
var base = lastSon(methods[0].ast).sym var base = lastSon(methods[0].ast).sym
result = base result = base
var paramLen = sonsLen(base.typ) var paramLen = sonsLen(base.typ)
var nilchecks = newNodeI(nkStmtList, base.info) var nilchecks = newNodeI(nkStmtList, base.info)
var disp = newNodeI(nkIfStmt, base.info) var disp = newNodeI(nkIfStmt, base.info)
var ands = getSysSym("and") var ands = getSysSym(g, unknownLineInfo(), "and")
var iss = getSysSym("of") var iss = getSysSym(g, unknownLineInfo(), "of")
let boolType = getSysType(g, unknownLineInfo(), tyBool)
for col in countup(1, paramLen - 1): for col in countup(1, paramLen - 1):
if contains(relevantCols, col): if contains(relevantCols, col):
let param = base.typ.n.sons[col].sym let param = base.typ.n.sons[col].sym
if param.typ.skipTypes(abstractInst).kind in {tyRef, tyPtr}: if param.typ.skipTypes(abstractInst).kind in {tyRef, tyPtr}:
addSon(nilchecks, newTree(nkCall, addSon(nilchecks, newTree(nkCall,
newSymNode(getCompilerProc"chckNilDisp"), newSymNode(param))) newSymNode(getCompilerProc(g, "chckNilDisp")), newSymNode(param)))
for meth in countup(0, high(methods)): for meth in countup(0, high(methods)):
var curr = methods[meth] # generate condition: var curr = methods[meth] # generate condition:
var cond: PNode = nil var cond: PNode = nil
for col in countup(1, paramLen - 1): for col in countup(1, paramLen - 1):
if contains(relevantCols, col): if contains(relevantCols, col):
var isn = newNodeIT(nkCall, base.info, getSysType(tyBool)) var isn = newNodeIT(nkCall, base.info, boolType)
addSon(isn, newSymNode(iss)) addSon(isn, newSymNode(iss))
let param = base.typ.n.sons[col].sym let param = base.typ.n.sons[col].sym
addSon(isn, newSymNode(param)) addSon(isn, newSymNode(param))
addSon(isn, newNodeIT(nkType, base.info, curr.typ.sons[col])) addSon(isn, newNodeIT(nkType, base.info, curr.typ.sons[col]))
if cond != nil: if cond != nil:
var a = newNodeIT(nkCall, base.info, getSysType(tyBool)) var a = newNodeIT(nkCall, base.info, boolType)
addSon(a, newSymNode(ands)) addSon(a, newSymNode(ands))
addSon(a, cond) addSon(a, cond)
addSon(a, isn) addSon(a, isn)
@ -262,7 +263,7 @@ proc genDispatcher(methods: TSymSeq, relevantCols: IntSet): PSym =
addSon(call, newSymNode(curr)) addSon(call, newSymNode(curr))
for col in countup(1, paramLen - 1): for col in countup(1, paramLen - 1):
addSon(call, genConv(newSymNode(base.typ.n.sons[col].sym), addSon(call, genConv(newSymNode(base.typ.n.sons[col].sym),
curr.typ.sons[col], false)) curr.typ.sons[col], false, g.config))
var ret: PNode var ret: PNode
if retTyp != nil: if retTyp != nil:
var a = newNodeI(nkFastAsgn, base.info) var a = newNodeI(nkFastAsgn, base.info)
@ -290,4 +291,4 @@ proc generateMethodDispatchers*(g: ModuleGraph): PNode =
if relevantCol(g.methods[bucket].methods, col): incl(relevantCols, col) if relevantCol(g.methods[bucket].methods, col): incl(relevantCols, col)
sortBucket(g.methods[bucket].methods, relevantCols) sortBucket(g.methods[bucket].methods, relevantCols)
addSon(result, addSon(result,
newSymNode(genDispatcher(g.methods[bucket].methods, relevantCols))) newSymNode(genDispatcher(g, g.methods[bucket].methods, relevantCols)))

View file

@ -221,7 +221,7 @@ errUseQualifier: "ambiguous identifier: '$1' -- use a qualifier",
errTypeExpected: "type expected", errTypeExpected: "type expected",
errSystemNeeds: "system module needs '$1'", errSystemNeeds: "system module needs '$1'",
errExecutionOfProgramFailed: "execution of an external program failed: '$1'", errExecutionOfProgramFailed: "execution of an external program failed: '$1'",
errNotOverloadable: "overloaded '$1' leads to ambiguous calls", errNotOverloadable: ,
errInvalidArgForX: "invalid argument for '$1'", errInvalidArgForX: "invalid argument for '$1'",
errStmtHasNoEffect: "statement has no effect", errStmtHasNoEffect: "statement has no effect",
errXExpectsTypeOrValue: "'$1' expects a type or value", errXExpectsTypeOrValue: "'$1' expects a type or value",
@ -305,7 +305,7 @@ errInvalidOrderInEnumX: "invalid order in enum '$1'",
errEnumXHasHoles: "enum '$1' has holes", errEnumXHasHoles: "enum '$1' has holes",
errExceptExpected: "'except' or 'finally' expected", errExceptExpected: "'except' or 'finally' expected",
errInvalidTry: "after catch all 'except' or 'finally' no section may follow", errInvalidTry: "after catch all 'except' or 'finally' no section may follow",
errOptionExpected: "option expected, but found '$1'", errOptionExpected: ,
errXisNoLabel: "'$1' is not a label", errXisNoLabel: "'$1' is not a label",
errNotAllCasesCovered: "not all cases are covered", errNotAllCasesCovered: "not all cases are covered",
errUnknownSubstitionVar: "unknown substitution variable: '$1'", errUnknownSubstitionVar: "unknown substitution variable: '$1'",

View file

@ -11,7 +11,7 @@
import import
intsets, strutils, os, ast, astalgo, msgs, options, idents, rodread, lookups, intsets, strutils, os, ast, astalgo, msgs, options, idents, rodread, lookups,
semdata, passes, renderer, modulepaths, sigmatch semdata, passes, renderer, modulepaths, sigmatch, configuration
proc evalImport*(c: PContext, n: PNode): PNode proc evalImport*(c: PContext, n: PNode): PNode
proc evalFrom*(c: PContext, n: PNode): PNode proc evalFrom*(c: PContext, n: PNode): PNode
@ -40,7 +40,7 @@ proc rawImportSymbol(c: PContext, s: PSym) =
for j in countup(0, sonsLen(etyp.n) - 1): for j in countup(0, sonsLen(etyp.n) - 1):
var e = etyp.n.sons[j].sym var e = etyp.n.sons[j].sym
if e.kind != skEnumField: if e.kind != skEnumField:
internalError(s.info, "rawImportSymbol") internalError(c.config, s.info, "rawImportSymbol")
# BUGFIX: because of aliases for enums the symbol may already # BUGFIX: because of aliases for enums the symbol may already
# have been put into the symbol table # have been put into the symbol table
# BUGFIX: but only iff they are the same symbols! # BUGFIX: but only iff they are the same symbols!
@ -62,14 +62,14 @@ proc rawImportSymbol(c: PContext, s: PSym) =
if hasPattern(s): addPattern(c, s) if hasPattern(s): addPattern(c, s)
proc importSymbol(c: PContext, n: PNode, fromMod: PSym) = proc importSymbol(c: PContext, n: PNode, fromMod: PSym) =
let ident = lookups.considerQuotedIdent(n) let ident = lookups.considerQuotedIdent(c.config, n)
let s = strTableGet(fromMod.tab, ident) let s = strTableGet(fromMod.tab, ident)
if s == nil: if s == nil:
errorUndeclaredIdentifier(c, n.info, ident.s) errorUndeclaredIdentifier(c, n.info, ident.s)
else: else:
if s.kind == skStub: loadStub(s) if s.kind == skStub: loadStub(s)
if s.kind notin ExportableSymKinds: if s.kind notin ExportableSymKinds:
internalError(n.info, "importSymbol: 2") internalError(c.config, n.info, "importSymbol: 2")
# for an enumeration we have to add all identifiers # for an enumeration we have to add all identifiers
case s.kind case s.kind
of skProcKinds: of skProcKinds:
@ -77,7 +77,7 @@ proc importSymbol(c: PContext, n: PNode, fromMod: PSym) =
var it: TIdentIter var it: TIdentIter
var e = initIdentIter(it, fromMod.tab, s.name) var e = initIdentIter(it, fromMod.tab, s.name)
while e != nil: while e != nil:
if e.name.id != s.name.id: internalError(n.info, "importSymbol: 3") if e.name.id != s.name.id: internalError(c.config, n.info, "importSymbol: 3")
rawImportSymbol(c, e) rawImportSymbol(c, e)
e = nextIdentIter(it, fromMod.tab) e = nextIdentIter(it, fromMod.tab)
else: rawImportSymbol(c, s) else: rawImportSymbol(c, s)
@ -89,7 +89,7 @@ proc importAllSymbolsExcept(c: PContext, fromMod: PSym, exceptSet: IntSet) =
if s.kind != skModule: if s.kind != skModule:
if s.kind != skEnumField: if s.kind != skEnumField:
if s.kind notin ExportableSymKinds: if s.kind notin ExportableSymKinds:
internalError(s.info, "importAllSymbols: " & $s.kind) internalError(c.config, s.info, "importAllSymbols: " & $s.kind)
if exceptSet.isNil or s.name.id notin exceptSet: if exceptSet.isNil or s.name.id notin exceptSet:
rawImportSymbol(c, s) rawImportSymbol(c, s)
s = nextIter(i, fromMod.tab) s = nextIter(i, fromMod.tab)
@ -110,22 +110,22 @@ proc importForwarded(c: PContext, n: PNode, exceptSet: IntSet) =
elif exceptSet.isNil or s.name.id notin exceptSet: elif exceptSet.isNil or s.name.id notin exceptSet:
rawImportSymbol(c, s) rawImportSymbol(c, s)
of nkExportExceptStmt: of nkExportExceptStmt:
localError(n.info, errGenerated, "'export except' not implemented") localError(c.config, n.info, "'export except' not implemented")
else: else:
for i in 0..safeLen(n)-1: for i in 0..safeLen(n)-1:
importForwarded(c, n.sons[i], exceptSet) importForwarded(c, n.sons[i], exceptSet)
proc importModuleAs(n: PNode, realModule: PSym): PSym = proc importModuleAs(c: PContext; n: PNode, realModule: PSym): PSym =
result = realModule result = realModule
if n.kind != nkImportAs: discard if n.kind != nkImportAs: discard
elif n.len != 2 or n.sons[1].kind != nkIdent: elif n.len != 2 or n.sons[1].kind != nkIdent:
localError(n.info, errGenerated, "module alias must be an identifier") localError(c.config, n.info, "module alias must be an identifier")
elif n.sons[1].ident.id != realModule.name.id: elif n.sons[1].ident.id != realModule.name.id:
# some misguided guy will write 'import abc.foo as foo' ... # some misguided guy will write 'import abc.foo as foo' ...
result = createModuleAlias(realModule, n.sons[1].ident, realModule.info) result = createModuleAlias(realModule, n.sons[1].ident, realModule.info)
proc myImportModule(c: PContext, n: PNode): PSym = proc myImportModule(c: PContext, n: PNode): PSym =
var f = checkModuleName(n) var f = checkModuleName(c.config, n)
if f != InvalidFileIDX: if f != InvalidFileIDX:
let L = c.graph.importStack.len let L = c.graph.importStack.len
let recursion = c.graph.importStack.find(f) let recursion = c.graph.importStack.find(f)
@ -138,7 +138,7 @@ proc myImportModule(c: PContext, n: PNode): PSym =
err.add toFullPath(c.graph.importStack[i]) & " imports " & err.add toFullPath(c.graph.importStack[i]) & " imports " &
toFullPath(c.graph.importStack[i+1]) toFullPath(c.graph.importStack[i+1])
c.recursiveDep = err c.recursiveDep = err
result = importModuleAs(n, gImportModule(c.graph, c.module, f, c.cache)) result = importModuleAs(c, n, gImportModule(c.graph, c.module, f, c.cache))
#echo "set back to ", L #echo "set back to ", L
c.graph.importStack.setLen(L) c.graph.importStack.setLen(L)
# we cannot perform this check reliably because of # we cannot perform this check reliably because of
@ -146,12 +146,12 @@ proc myImportModule(c: PContext, n: PNode): PSym =
when true: when true:
if result.info.fileIndex == c.module.info.fileIndex and if result.info.fileIndex == c.module.info.fileIndex and
result.info.fileIndex == n.info.fileIndex: result.info.fileIndex == n.info.fileIndex:
localError(n.info, errGenerated, "A module cannot import itself") localError(c.config, n.info, "A module cannot import itself")
if sfDeprecated in result.flags: if sfDeprecated in result.flags:
if result.constraint != nil: if result.constraint != nil:
message(n.info, warnDeprecated, result.constraint.strVal & "; " & result.name.s) message(c.config, n.info, warnDeprecated, result.constraint.strVal & "; " & result.name.s)
else: else:
message(n.info, warnDeprecated, result.name.s) message(c.config, n.info, warnDeprecated, result.name.s)
suggestSym(n.info, result, c.graph.usageSym, false) suggestSym(n.info, result, c.graph.usageSym, false)
proc impMod(c: PContext; it: PNode) = proc impMod(c: PContext; it: PNode) =
@ -182,7 +182,7 @@ proc evalImport(c: PContext, n: PNode): PNode =
proc evalFrom(c: PContext, n: PNode): PNode = proc evalFrom(c: PContext, n: PNode): PNode =
result = n result = n
checkMinSonsLen(n, 2) checkMinSonsLen(n, 2, c.config)
var m = myImportModule(c, n.sons[0]) var m = myImportModule(c, n.sons[0])
if m != nil: if m != nil:
n.sons[0] = newSymNode(m) n.sons[0] = newSymNode(m)
@ -193,14 +193,14 @@ proc evalFrom(c: PContext, n: PNode): PNode =
proc evalImportExcept*(c: PContext, n: PNode): PNode = proc evalImportExcept*(c: PContext, n: PNode): PNode =
result = n result = n
checkMinSonsLen(n, 2) checkMinSonsLen(n, 2, c.config)
var m = myImportModule(c, n.sons[0]) var m = myImportModule(c, n.sons[0])
if m != nil: if m != nil:
n.sons[0] = newSymNode(m) n.sons[0] = newSymNode(m)
addDecl(c, m, n.info) # add symbol to symbol table of module addDecl(c, m, n.info) # add symbol to symbol table of module
var exceptSet = initIntSet() var exceptSet = initIntSet()
for i in countup(1, sonsLen(n) - 1): for i in countup(1, sonsLen(n) - 1):
let ident = lookups.considerQuotedIdent(n.sons[i]) let ident = lookups.considerQuotedIdent(c.config, n.sons[i])
exceptSet.incl(ident.id) exceptSet.incl(ident.id)
importAllSymbolsExcept(c, m, exceptSet) importAllSymbolsExcept(c, m, exceptSet)
#importForwarded(c, m.ast, exceptSet) #importForwarded(c, m.ast, exceptSet)

File diff suppressed because it is too large Load diff

View file

@ -14,14 +14,12 @@ import
ast, astalgo, msgs, semdata, types, trees, strutils ast, astalgo, msgs, semdata, types, trees, strutils
proc equalGenericParams(procA, procB: PNode): bool = proc equalGenericParams(procA, procB: PNode): bool =
if sonsLen(procA) != sonsLen(procB): return if sonsLen(procA) != sonsLen(procB): return false
for i in countup(0, sonsLen(procA) - 1): for i in countup(0, sonsLen(procA) - 1):
if procA.sons[i].kind != nkSym: if procA.sons[i].kind != nkSym:
internalError(procA.info, "equalGenericParams") return false
return
if procB.sons[i].kind != nkSym: if procB.sons[i].kind != nkSym:
internalError(procB.info, "equalGenericParams") return false
return
let a = procA.sons[i].sym let a = procA.sons[i].sym
let b = procB.sons[i].sym let b = procB.sons[i].sym
if a.name.id != b.name.id or if a.name.id != b.name.id or
@ -57,7 +55,7 @@ proc searchForProcOld*(c: PContext, scope: PScope, fn: PSym): PSym =
of paramsEqual: of paramsEqual:
return return
of paramsIncompatible: of paramsIncompatible:
localError(fn.info, errNotOverloadable, fn.name.s) localError(c.config, fn.info, "overloaded '$1' leads to ambiguous calls" % fn.name.s)
return return
of paramsNotEqual: of paramsNotEqual:
discard discard
@ -76,10 +74,10 @@ proc searchForProcNew(c: PContext, scope: PScope, fn: PSym): PSym =
let message = ("public implementation '$1' has non-public " & let message = ("public implementation '$1' has non-public " &
"forward declaration in $2") % "forward declaration in $2") %
[getProcHeader(result), $result.info] [getProcHeader(result), $result.info]
localError(fn.info, errGenerated, message) localError(c.config, fn.info, message)
return return
of paramsIncompatible: of paramsIncompatible:
localError(fn.info, errNotOverloadable, fn.name.s) localError(c.config, fn.info, "overloaded '$1' leads to ambiguous calls" % fn.name.s)
return return
of paramsNotEqual: of paramsNotEqual:
discard discard