semdata.nim 15 KB

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