semdata.nim 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. #
  2. #
  3. # The Nim Compiler
  4. # (c) Copyright 2017 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. ## This module contains the data structures for the semantic checking phase.
  10. import
  11. intsets, options, ast, astalgo, msgs, idents, renderer,
  12. magicsys, vmdef, modulegraphs, lineinfos, sets
  13. type
  14. TOptionEntry* = object # entries to put on a stack for pragma parsing
  15. options*: TOptions
  16. defaultCC*: TCallingConvention
  17. dynlib*: PLib
  18. notes*: TNoteKinds
  19. features*: set[Feature]
  20. otherPragmas*: PNode # every pragma can be pushed
  21. POptionEntry* = ref TOptionEntry
  22. PProcCon* = ref TProcCon
  23. TProcCon* = object # procedure context; also used for top-level
  24. # statements
  25. owner*: PSym # the symbol this context belongs to
  26. resultSym*: PSym # the result symbol (if we are in a proc)
  27. selfSym*: PSym # the 'self' symbol (if available)
  28. nestedLoopCounter*: int # whether we are in a loop or not
  29. nestedBlockCounter*: int # whether we are in a block or not
  30. inTryStmt*: int # whether we are in a try statement; works also
  31. # in standalone ``except`` and ``finally``
  32. next*: PProcCon # used for stacking procedure contexts
  33. wasForwarded*: bool # whether the current proc has a separate header
  34. mappingExists*: bool
  35. mapping*: TIdTable
  36. caseContext*: seq[tuple[n: PNode, idx: int]]
  37. TMatchedConcept* = object
  38. candidateType*: PType
  39. prev*: ptr TMatchedConcept
  40. depth*: int
  41. TInstantiationPair* = object
  42. genericSym*: PSym
  43. inst*: PInstantiation
  44. TExprFlag* = enum
  45. efLValue, efWantIterator, efInTypeof,
  46. efNeedStatic,
  47. # Use this in contexts where a static value is mandatory
  48. efPreferStatic,
  49. # Use this in contexts where a static value could bring more
  50. # information, but it's not strictly mandatory. This may become
  51. # the default with implicit statics in the future.
  52. efPreferNilResult,
  53. # Use this if you want a certain result (e.g. static value),
  54. # but you don't want to trigger a hard error. For example,
  55. # you may be in position to supply a better error message
  56. # to the user.
  57. efWantStmt, efAllowStmt, efDetermineType, efExplain,
  58. efAllowDestructor, efWantValue, efOperand, efNoSemCheck,
  59. efNoEvaluateGeneric, efInCall, efFromHlo,
  60. efNoUndeclared
  61. # Use this if undeclared identifiers should not raise an error during
  62. # overload resolution.
  63. TExprFlags* = set[TExprFlag]
  64. PContext* = ref TContext
  65. TContext* = object of TPassContext # a context represents the module
  66. # that is currently being compiled
  67. enforceVoidContext*: PType
  68. module*: PSym # the module sym belonging to the context
  69. currentScope*: PScope # current scope
  70. importTable*: PScope # scope for all imported symbols
  71. topLevelScope*: PScope # scope for all top-level symbols
  72. p*: PProcCon # procedure context
  73. matchedConcept*: ptr TMatchedConcept # the current concept being matched
  74. friendModules*: seq[PSym] # friend modules; may access private data;
  75. # this is used so that generic instantiations
  76. # can access private object fields
  77. instCounter*: int # to prevent endless instantiations
  78. ambiguousSymbols*: IntSet # ids of all ambiguous symbols (cannot
  79. # store this info in the syms themselves!)
  80. inGenericContext*: int # > 0 if we are in a generic type
  81. inStaticContext*: int # > 0 if we are inside a static: block
  82. inUnrolledContext*: int # > 0 if we are unrolling a loop
  83. compilesContextId*: int # > 0 if we are in a ``compiles`` magic
  84. compilesContextIdGenerator*: int
  85. inGenericInst*: int # > 0 if we are instantiating a generic
  86. converters*: seq[PSym]
  87. patterns*: seq[PSym] # sequence of pattern matchers
  88. optionStack*: seq[POptionEntry]
  89. symMapping*: TIdTable # every gensym'ed symbol needs to be mapped
  90. # to some new symbol in a generic instantiation
  91. libs*: seq[PLib] # all libs used by this module
  92. semConstExpr*: proc (c: PContext, n: PNode): PNode {.nimcall.} # for the pragmas
  93. semExpr*: proc (c: PContext, n: PNode, flags: TExprFlags = {}): PNode {.nimcall.}
  94. semTryExpr*: proc (c: PContext, n: PNode, flags: TExprFlags = {}): PNode {.nimcall.}
  95. semTryConstExpr*: proc (c: PContext, n: PNode): PNode {.nimcall.}
  96. semOperand*: proc (c: PContext, n: PNode, flags: TExprFlags = {}): PNode {.nimcall.}
  97. semConstBoolExpr*: proc (c: PContext, n: PNode): PNode {.nimcall.} # XXX bite the bullet
  98. semOverloadedCall*: proc (c: PContext, n, nOrig: PNode,
  99. filter: TSymKinds, flags: TExprFlags): PNode {.nimcall.}
  100. semTypeNode*: proc(c: PContext, n: PNode, prev: PType): PType {.nimcall.}
  101. semInferredLambda*: proc(c: PContext, pt: TIdTable, n: PNode): PNode
  102. semGenerateInstance*: proc (c: PContext, fn: PSym, pt: TIdTable,
  103. info: TLineInfo): PSym
  104. includedFiles*: IntSet # used to detect recursive include files
  105. pureEnumFields*: TStrTable # pure enum fields that can be used unambiguously
  106. userPragmas*: TStrTable
  107. evalContext*: PEvalContext
  108. unknownIdents*: IntSet # ids of all unknown identifiers to prevent
  109. # naming it multiple times
  110. generics*: seq[TInstantiationPair] # pending list of instantiated generics to compile
  111. topStmts*: int # counts the number of encountered top level statements
  112. lastGenericIdx*: int # used for the generics stack
  113. hloLoopDetector*: int # used to prevent endless loops in the HLO
  114. inParallelStmt*: int
  115. instTypeBoundOp*: proc (c: PContext; dc: PSym; t: PType; info: TLineInfo;
  116. op: TTypeAttachedOp; col: int): PSym {.nimcall.}
  117. selfName*: PIdent
  118. cache*: IdentCache
  119. graph*: ModuleGraph
  120. signatures*: TStrTable
  121. recursiveDep*: string
  122. suggestionsMade*: bool
  123. features*: set[Feature]
  124. inTypeContext*: int
  125. typesWithOps*: seq[(PType, PType)] #\
  126. # We need to instantiate the type bound ops lazily after
  127. # the generic type has been constructed completely. See
  128. # tests/destructor/topttree.nim for an example that
  129. # would otherwise fail.
  130. unusedImports*: seq[(PSym, TLineInfo)]
  131. exportIndirections*: HashSet[(int, int)]
  132. template config*(c: PContext): ConfigRef = c.graph.config
  133. proc makeInstPair*(s: PSym, inst: PInstantiation): TInstantiationPair =
  134. result.genericSym = s
  135. result.inst = inst
  136. proc filename*(c: PContext): string =
  137. # the module's filename
  138. return toFilename(c.config, FileIndex c.module.position)
  139. proc scopeDepth*(c: PContext): int {.inline.} =
  140. result = if c.currentScope != nil: c.currentScope.depthLevel
  141. else: 0
  142. proc getCurrOwner*(c: PContext): PSym =
  143. # owner stack (used for initializing the
  144. # owner field of syms)
  145. # the documentation comment always gets
  146. # assigned to the current owner
  147. result = c.graph.owners[^1]
  148. proc pushOwner*(c: PContext; owner: PSym) =
  149. add(c.graph.owners, owner)
  150. proc popOwner*(c: PContext) =
  151. var length = len(c.graph.owners)
  152. if length > 0: setLen(c.graph.owners, length - 1)
  153. else: internalError(c.config, "popOwner")
  154. proc lastOptionEntry*(c: PContext): POptionEntry =
  155. result = c.optionStack[^1]
  156. proc popProcCon*(c: PContext) {.inline.} = c.p = c.p.next
  157. proc put*(p: PProcCon; key, val: PSym) =
  158. if not p.mappingExists:
  159. initIdTable(p.mapping)
  160. p.mappingExists = true
  161. #echo "put into table ", key.info
  162. p.mapping.idTablePut(key, val)
  163. proc get*(p: PProcCon; key: PSym): PSym =
  164. if not p.mappingExists: return nil
  165. result = PSym(p.mapping.idTableGet(key))
  166. proc getGenSym*(c: PContext; s: PSym): PSym =
  167. if sfGenSym notin s.flags: return s
  168. var it = c.p
  169. while it != nil:
  170. result = get(it, s)
  171. if result != nil:
  172. #echo "got from table ", result.name.s, " ", result.info
  173. return result
  174. it = it.next
  175. result = s
  176. proc considerGenSyms*(c: PContext; n: PNode) =
  177. if n.kind == nkSym:
  178. let s = getGenSym(c, n.sym)
  179. if n.sym != s:
  180. n.sym = s
  181. else:
  182. for i in 0..<n.safeLen:
  183. considerGenSyms(c, n.sons[i])
  184. proc newOptionEntry*(conf: ConfigRef): POptionEntry =
  185. new(result)
  186. result.options = conf.options
  187. result.defaultCC = ccDefault
  188. result.dynlib = nil
  189. result.notes = conf.notes
  190. proc pushOptionEntry*(c: PContext): POptionEntry =
  191. new(result)
  192. var prev = c.optionStack[^1]
  193. result.options = c.config.options
  194. result.defaultCC = prev.defaultCC
  195. result.dynlib = prev.dynlib
  196. result.notes = c.config.notes
  197. result.features = c.features
  198. c.optionStack.add(result)
  199. proc popOptionEntry*(c: PContext) =
  200. c.config.options = c.optionStack[^1].options
  201. c.config.notes = c.optionStack[^1].notes
  202. c.features = c.optionStack[^1].features
  203. c.optionStack.setLen(c.optionStack.len - 1)
  204. proc newContext*(graph: ModuleGraph; module: PSym): PContext =
  205. new(result)
  206. result.enforceVoidContext = PType(kind: tyTyped)
  207. result.ambiguousSymbols = initIntSet()
  208. result.optionStack = @[newOptionEntry(graph.config)]
  209. result.libs = @[]
  210. result.module = module
  211. result.friendModules = @[module]
  212. result.converters = @[]
  213. result.patterns = @[]
  214. result.includedFiles = initIntSet()
  215. initStrTable(result.pureEnumFields)
  216. initStrTable(result.userPragmas)
  217. result.generics = @[]
  218. result.unknownIdents = initIntSet()
  219. result.cache = graph.cache
  220. result.graph = graph
  221. initStrTable(result.signatures)
  222. result.typesWithOps = @[]
  223. result.features = graph.config.features
  224. proc inclSym(sq: var seq[PSym], s: PSym) =
  225. var L = len(sq)
  226. for i in 0 ..< L:
  227. if sq[i].id == s.id: return
  228. setLen(sq, L + 1)
  229. sq[L] = s
  230. proc addConverter*(c: PContext, conv: PSym) =
  231. inclSym(c.converters, conv)
  232. proc addPattern*(c: PContext, p: PSym) =
  233. inclSym(c.patterns, p)
  234. proc newLib*(kind: TLibKind): PLib =
  235. new(result)
  236. result.kind = kind #initObjectSet(result.syms)
  237. proc addToLib*(lib: PLib, sym: PSym) =
  238. #if sym.annex != nil and not isGenericRoutine(sym):
  239. # LocalError(sym.info, errInvalidPragma)
  240. sym.annex = lib
  241. proc newTypeS*(kind: TTypeKind, c: PContext): PType =
  242. result = newType(kind, getCurrOwner(c))
  243. proc makePtrType*(c: PContext, baseType: PType): PType =
  244. result = newTypeS(tyPtr, c)
  245. addSonSkipIntLit(result, baseType)
  246. proc makeTypeWithModifier*(c: PContext,
  247. modifier: TTypeKind,
  248. baseType: PType): PType =
  249. assert modifier in {tyVar, tyLent, tyPtr, tyRef, tyStatic, tyTypeDesc}
  250. if modifier in {tyVar, tyLent, tyTypeDesc} and baseType.kind == modifier:
  251. result = baseType
  252. else:
  253. result = newTypeS(modifier, c)
  254. addSonSkipIntLit(result, baseType)
  255. proc makeVarType*(c: PContext, baseType: PType; kind = tyVar): PType =
  256. if baseType.kind == kind:
  257. result = baseType
  258. else:
  259. result = newTypeS(kind, c)
  260. addSonSkipIntLit(result, baseType)
  261. proc makeVarType*(owner: PSym, baseType: PType; kind = tyVar): PType =
  262. if baseType.kind == kind:
  263. result = baseType
  264. else:
  265. result = newType(kind, owner)
  266. addSonSkipIntLit(result, baseType)
  267. proc makeTypeDesc*(c: PContext, typ: PType): PType =
  268. if typ.kind == tyTypeDesc:
  269. result = typ
  270. else:
  271. result = newTypeS(tyTypeDesc, c)
  272. incl result.flags, tfCheckedForDestructor
  273. result.addSonSkipIntLit(typ)
  274. proc makeTypeSymNode*(c: PContext, typ: PType, info: TLineInfo): PNode =
  275. let typedesc = newTypeS(tyTypeDesc, c)
  276. incl typedesc.flags, tfCheckedForDestructor
  277. typedesc.addSonSkipIntLit(assertNotNil(c.config, typ))
  278. let sym = newSym(skType, c.cache.idAnon, getCurrOwner(c), info,
  279. c.config.options).linkTo(typedesc)
  280. return newSymNode(sym, info)
  281. proc makeTypeFromExpr*(c: PContext, n: PNode): PType =
  282. result = newTypeS(tyFromExpr, c)
  283. assert n != nil
  284. result.n = n
  285. proc newTypeWithSons*(owner: PSym, kind: TTypeKind, sons: seq[PType]): PType =
  286. result = newType(kind, owner)
  287. result.sons = sons
  288. proc newTypeWithSons*(c: PContext, kind: TTypeKind,
  289. sons: seq[PType]): PType =
  290. result = newType(kind, getCurrOwner(c))
  291. result.sons = sons
  292. proc makeStaticExpr*(c: PContext, n: PNode): PNode =
  293. result = newNodeI(nkStaticExpr, n.info)
  294. result.sons = @[n]
  295. result.typ = if n.typ != nil and n.typ.kind == tyStatic: n.typ
  296. else: newTypeWithSons(c, tyStatic, @[n.typ])
  297. proc makeAndType*(c: PContext, t1, t2: PType): PType =
  298. result = newTypeS(tyAnd, c)
  299. result.sons = @[t1, t2]
  300. propagateToOwner(result, t1)
  301. propagateToOwner(result, t2)
  302. result.flags.incl((t1.flags + t2.flags) * {tfHasStatic})
  303. result.flags.incl tfHasMeta
  304. proc makeOrType*(c: PContext, t1, t2: PType): PType =
  305. result = newTypeS(tyOr, c)
  306. if t1.kind != tyOr and t2.kind != tyOr:
  307. result.sons = @[t1, t2]
  308. else:
  309. template addOr(t1) =
  310. if t1.kind == tyOr:
  311. for x in t1.sons: result.rawAddSon x
  312. else:
  313. result.rawAddSon t1
  314. addOr(t1)
  315. addOr(t2)
  316. propagateToOwner(result, t1)
  317. propagateToOwner(result, t2)
  318. result.flags.incl((t1.flags + t2.flags) * {tfHasStatic})
  319. result.flags.incl tfHasMeta
  320. proc makeNotType*(c: PContext, t1: PType): PType =
  321. result = newTypeS(tyNot, c)
  322. result.sons = @[t1]
  323. propagateToOwner(result, t1)
  324. result.flags.incl(t1.flags * {tfHasStatic})
  325. result.flags.incl tfHasMeta
  326. proc nMinusOne(c: PContext; n: PNode): PNode =
  327. result = newNode(nkCall, n.info, @[
  328. newSymNode(getSysMagic(c.graph, n.info, "pred", mPred)), n])
  329. # Remember to fix the procs below this one when you make changes!
  330. proc makeRangeWithStaticExpr*(c: PContext, n: PNode): PType =
  331. let intType = getSysType(c.graph, n.info, tyInt)
  332. result = newTypeS(tyRange, c)
  333. result.sons = @[intType]
  334. if n.typ != nil and n.typ.n == nil:
  335. result.flags.incl tfUnresolved
  336. result.n = newNode(nkRange, n.info, @[
  337. newIntTypeNode(0, intType),
  338. makeStaticExpr(c, nMinusOne(c, n))])
  339. template rangeHasUnresolvedStatic*(t: PType): bool =
  340. tfUnresolved in t.flags
  341. proc errorType*(c: PContext): PType =
  342. ## creates a type representing an error state
  343. result = newTypeS(tyError, c)
  344. result.flags.incl tfCheckedForDestructor
  345. proc errorNode*(c: PContext, n: PNode): PNode =
  346. result = newNodeI(nkEmpty, n.info)
  347. result.typ = errorType(c)
  348. proc fillTypeS*(dest: PType, kind: TTypeKind, c: PContext) =
  349. dest.kind = kind
  350. dest.owner = getCurrOwner(c)
  351. dest.size = - 1
  352. proc makeRangeType*(c: PContext; first, last: BiggestInt;
  353. info: TLineInfo; intType: PType = nil): PType =
  354. let intType = if intType != nil: intType else: getSysType(c.graph, info, tyInt)
  355. var n = newNodeI(nkRange, info)
  356. addSon(n, newIntTypeNode(first, intType))
  357. addSon(n, newIntTypeNode(last, intType))
  358. result = newTypeS(tyRange, c)
  359. result.n = n
  360. addSonSkipIntLit(result, intType) # basetype of range
  361. proc markIndirect*(c: PContext, s: PSym) {.inline.} =
  362. if s.kind in {skProc, skFunc, skConverter, skMethod, skIterator}:
  363. incl(s.flags, sfAddrTaken)
  364. # XXX add to 'c' for global analysis
  365. proc illFormedAst*(n: PNode; conf: ConfigRef) =
  366. globalError(conf, n.info, errIllFormedAstX, renderTree(n, {renderNoComments}))
  367. proc illFormedAstLocal*(n: PNode; conf: ConfigRef) =
  368. localError(conf, n.info, errIllFormedAstX, renderTree(n, {renderNoComments}))
  369. proc checkSonsLen*(n: PNode, length: int; conf: ConfigRef) =
  370. if len(n) != length: illFormedAst(n, conf)
  371. proc checkMinSonsLen*(n: PNode, length: int; conf: ConfigRef) =
  372. if len(n) < length: illFormedAst(n, conf)
  373. proc isTopLevel*(c: PContext): bool {.inline.} =
  374. result = c.currentScope.depthLevel <= 2
  375. proc pushCaseContext*(c: PContext, caseNode: PNode) =
  376. add(c.p.caseContext, (caseNode, 0))
  377. proc popCaseContext*(c: PContext) =
  378. discard pop(c.p.caseContext)
  379. proc setCaseContextIdx*(c: PContext, idx: int) =
  380. c.p.caseContext[^1].idx = idx