semdata.nim 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644
  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 tables
  11. when defined(nimPreviewSlimSystem):
  12. import std/assertions
  13. import
  14. intsets, options, ast, astalgo, msgs, idents, renderer,
  15. magicsys, vmdef, modulegraphs, lineinfos, sets, pathutils
  16. import ic / ic
  17. type
  18. TOptionEntry* = object # entries to put on a stack for pragma parsing
  19. options*: TOptions
  20. defaultCC*: TCallingConvention
  21. dynlib*: PLib
  22. notes*: TNoteKinds
  23. features*: set[Feature]
  24. otherPragmas*: PNode # every pragma can be pushed
  25. warningAsErrors*: TNoteKinds
  26. POptionEntry* = ref TOptionEntry
  27. PProcCon* = ref TProcCon
  28. TProcCon* {.acyclic.} = object # procedure context; also used for top-level
  29. # statements
  30. owner*: PSym # the symbol this context belongs to
  31. resultSym*: PSym # the result symbol (if we are in a proc)
  32. nestedLoopCounter*: int # whether we are in a loop or not
  33. nestedBlockCounter*: int # whether we are in a block or not
  34. breakInLoop*: bool # whether we are in a loop without block
  35. next*: PProcCon # used for stacking procedure contexts
  36. mappingExists*: bool
  37. mapping*: TIdTable
  38. caseContext*: seq[tuple[n: PNode, idx: int]]
  39. localBindStmts*: seq[PNode]
  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, efWantIterable, 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. efWantValue, efOperand, efNoSemCheck,
  62. efNoEvaluateGeneric, efInCall, efFromHlo, efNoSem2Check,
  63. efNoUndeclared, efIsDotCall, efCannotBeDotCall,
  64. # Use this if undeclared identifiers should not raise an error during
  65. # overload resolution.
  66. efNoDiagnostics,
  67. efTypeAllowed # typeAllowed will be called after
  68. efWantNoDefaults
  69. TExprFlags* = set[TExprFlag]
  70. ImportMode* = enum
  71. importAll, importSet, importExcept
  72. ImportedModule* = object
  73. m*: PSym
  74. case mode*: ImportMode
  75. of importAll: discard
  76. of importSet:
  77. imported*: IntSet # of PIdent.id
  78. of importExcept:
  79. exceptSet*: IntSet # of PIdent.id
  80. PContext* = ref TContext
  81. TContext* = object of TPassContext # a context represents the module
  82. # that is currently being compiled
  83. enforceVoidContext*: PType
  84. # for `if cond: stmt else: foo`, `foo` will be evaluated under
  85. # enforceVoidContext != nil
  86. voidType*: PType # for typeof(stmt)
  87. module*: PSym # the module sym belonging to the context
  88. currentScope*: PScope # current scope
  89. moduleScope*: PScope # scope for modules
  90. imports*: seq[ImportedModule] # scope for all imported symbols
  91. topLevelScope*: PScope # scope for all top-level symbols
  92. p*: PProcCon # procedure context
  93. intTypeCache*: array[-5..32, PType] # cache some common integer types
  94. # to avoid type allocations
  95. nilTypeCache*: PType
  96. matchedConcept*: ptr TMatchedConcept # the current concept being matched
  97. friendModules*: seq[PSym] # friend modules; may access private data;
  98. # this is used so that generic instantiations
  99. # can access private object fields
  100. instCounter*: int # to prevent endless instantiations
  101. templInstCounter*: ref int # gives every template instantiation a unique id
  102. inGenericContext*: int # > 0 if we are in a generic type
  103. inStaticContext*: int # > 0 if we are inside a static: block
  104. inUnrolledContext*: int # > 0 if we are unrolling a loop
  105. compilesContextId*: int # > 0 if we are in a ``compiles`` magic
  106. compilesContextIdGenerator*: int
  107. inGenericInst*: int # > 0 if we are instantiating a generic
  108. converters*: seq[PSym]
  109. patterns*: seq[PSym] # sequence of pattern matchers
  110. optionStack*: seq[POptionEntry]
  111. symMapping*: TIdTable # every gensym'ed symbol needs to be mapped
  112. # to some new symbol in a generic instantiation
  113. libs*: seq[PLib] # all libs used by this module
  114. semConstExpr*: proc (c: PContext, n: PNode; expectedType: PType = nil): PNode {.nimcall.} # for the pragmas
  115. semExpr*: proc (c: PContext, n: PNode, flags: TExprFlags = {}, expectedType: PType = nil): PNode {.nimcall.}
  116. semExprWithType*: proc (c: PContext, n: PNode, flags: TExprFlags = {}, expectedType: PType = nil): PNode {.nimcall.}
  117. semTryExpr*: proc (c: PContext, n: PNode, flags: TExprFlags = {}): PNode {.nimcall.}
  118. semTryConstExpr*: proc (c: PContext, n: PNode; expectedType: PType = nil): PNode {.nimcall.}
  119. computeRequiresInit*: proc (c: PContext, t: PType): bool {.nimcall.}
  120. hasUnresolvedArgs*: proc (c: PContext, n: PNode): bool
  121. semOperand*: proc (c: PContext, n: PNode, flags: TExprFlags = {}): PNode {.nimcall.}
  122. semConstBoolExpr*: proc (c: PContext, n: PNode): PNode {.nimcall.} # XXX bite the bullet
  123. semOverloadedCall*: proc (c: PContext, n, nOrig: PNode,
  124. filter: TSymKinds, flags: TExprFlags, expectedType: PType = nil): PNode {.nimcall.}
  125. semTypeNode*: proc(c: PContext, n: PNode, prev: PType): PType {.nimcall.}
  126. semInferredLambda*: proc(c: PContext, pt: TIdTable, n: PNode): PNode
  127. semGenerateInstance*: proc (c: PContext, fn: PSym, pt: TIdTable,
  128. info: TLineInfo): PSym
  129. includedFiles*: IntSet # used to detect recursive include files
  130. pureEnumFields*: TStrTable # pure enum fields that can be used unambiguously
  131. userPragmas*: TStrTable
  132. evalContext*: PEvalContext
  133. unknownIdents*: IntSet # ids of all unknown identifiers to prevent
  134. # naming it multiple times
  135. generics*: seq[TInstantiationPair] # pending list of instantiated generics to compile
  136. topStmts*: int # counts the number of encountered top level statements
  137. lastGenericIdx*: int # used for the generics stack
  138. hloLoopDetector*: int # used to prevent endless loops in the HLO
  139. inParallelStmt*: int
  140. instTypeBoundOp*: proc (c: PContext; dc: PSym; t: PType; info: TLineInfo;
  141. op: TTypeAttachedOp; col: int): PSym {.nimcall.}
  142. cache*: IdentCache
  143. graph*: ModuleGraph
  144. signatures*: TStrTable
  145. recursiveDep*: string
  146. suggestionsMade*: bool
  147. isAmbiguous*: bool # little hack
  148. features*: set[Feature]
  149. inTypeContext*, inConceptDecl*: int
  150. unusedImports*: seq[(PSym, TLineInfo)]
  151. exportIndirections*: HashSet[(int, int)] # (module.id, symbol.id)
  152. importModuleMap*: Table[int, int] # (module.id, module.id)
  153. lastTLineInfo*: TLineInfo
  154. sideEffects*: Table[int, seq[(TLineInfo, PSym)]] # symbol.id index
  155. inUncheckedAssignSection*: int
  156. importModuleLookup*: Table[int, seq[int]] # (module.ident.id, [module.id])
  157. skipTypes*: seq[PNode] # used to skip types between passes in type section. So far only used for inheritance, sets and generic bodies.
  158. TBorrowState* = enum
  159. bsNone, bsReturnNotMatch, bsNoDistinct, bsGeneric, bsNotSupported, bsMatch
  160. template config*(c: PContext): ConfigRef = c.graph.config
  161. proc getIntLitType*(c: PContext; literal: PNode): PType =
  162. # we cache some common integer literal types for performance:
  163. let value = literal.intVal
  164. if value >= low(c.intTypeCache) and value <= high(c.intTypeCache):
  165. result = c.intTypeCache[value.int]
  166. if result == nil:
  167. let ti = getSysType(c.graph, literal.info, tyInt)
  168. result = copyType(ti, nextTypeId(c.idgen), ti.owner)
  169. result.n = literal
  170. c.intTypeCache[value.int] = result
  171. else:
  172. let ti = getSysType(c.graph, literal.info, tyInt)
  173. result = copyType(ti, nextTypeId(c.idgen), ti.owner)
  174. result.n = literal
  175. proc setIntLitType*(c: PContext; result: PNode) =
  176. let i = result.intVal
  177. case c.config.target.intSize
  178. of 8: result.typ = getIntLitType(c, result)
  179. of 4:
  180. if i >= low(int32) and i <= high(int32):
  181. result.typ = getIntLitType(c, result)
  182. else:
  183. result.typ = getSysType(c.graph, result.info, tyInt64)
  184. of 2:
  185. if i >= low(int16) and i <= high(int16):
  186. result.typ = getIntLitType(c, result)
  187. elif i >= low(int32) and i <= high(int32):
  188. result.typ = getSysType(c.graph, result.info, tyInt32)
  189. else:
  190. result.typ = getSysType(c.graph, result.info, tyInt64)
  191. of 1:
  192. # 8 bit CPUs are insane ...
  193. if i >= low(int8) and i <= high(int8):
  194. result.typ = getIntLitType(c, result)
  195. elif i >= low(int16) and i <= high(int16):
  196. result.typ = getSysType(c.graph, result.info, tyInt16)
  197. elif i >= low(int32) and i <= high(int32):
  198. result.typ = getSysType(c.graph, result.info, tyInt32)
  199. else:
  200. result.typ = getSysType(c.graph, result.info, tyInt64)
  201. else:
  202. internalError(c.config, result.info, "invalid int size")
  203. proc makeInstPair*(s: PSym, inst: PInstantiation): TInstantiationPair =
  204. result.genericSym = s
  205. result.inst = inst
  206. proc filename*(c: PContext): string =
  207. # the module's filename
  208. return toFilename(c.config, FileIndex c.module.position)
  209. proc scopeDepth*(c: PContext): int {.inline.} =
  210. result = if c.currentScope != nil: c.currentScope.depthLevel
  211. else: 0
  212. proc getCurrOwner*(c: PContext): PSym =
  213. # owner stack (used for initializing the
  214. # owner field of syms)
  215. # the documentation comment always gets
  216. # assigned to the current owner
  217. result = c.graph.owners[^1]
  218. proc pushOwner*(c: PContext; owner: PSym) =
  219. c.graph.owners.add(owner)
  220. proc popOwner*(c: PContext) =
  221. if c.graph.owners.len > 0: setLen(c.graph.owners, c.graph.owners.len - 1)
  222. else: internalError(c.config, "popOwner")
  223. proc lastOptionEntry*(c: PContext): POptionEntry =
  224. result = c.optionStack[^1]
  225. proc popProcCon*(c: PContext) {.inline.} = c.p = c.p.next
  226. proc put*(p: PProcCon; key, val: PSym) =
  227. if not p.mappingExists:
  228. p.mapping = initIdTable()
  229. p.mappingExists = true
  230. #echo "put into table ", key.info
  231. p.mapping.idTablePut(key, val)
  232. proc get*(p: PProcCon; key: PSym): PSym =
  233. if not p.mappingExists: return nil
  234. result = PSym(p.mapping.idTableGet(key))
  235. proc getGenSym*(c: PContext; s: PSym): PSym =
  236. if sfGenSym notin s.flags: return s
  237. var it = c.p
  238. while it != nil:
  239. result = get(it, s)
  240. if result != nil:
  241. #echo "got from table ", result.name.s, " ", result.info
  242. return result
  243. it = it.next
  244. result = s
  245. proc considerGenSyms*(c: PContext; n: PNode) =
  246. if n == nil:
  247. discard "can happen for nkFormalParams/nkArgList"
  248. elif n.kind == nkSym:
  249. let s = getGenSym(c, n.sym)
  250. if n.sym != s:
  251. n.sym = s
  252. else:
  253. for i in 0..<n.safeLen:
  254. considerGenSyms(c, n[i])
  255. proc newOptionEntry*(conf: ConfigRef): POptionEntry =
  256. new(result)
  257. result.options = conf.options
  258. result.defaultCC = ccNimCall
  259. result.dynlib = nil
  260. result.notes = conf.notes
  261. result.warningAsErrors = conf.warningAsErrors
  262. proc pushOptionEntry*(c: PContext): POptionEntry =
  263. new(result)
  264. var prev = c.optionStack[^1]
  265. result.options = c.config.options
  266. result.defaultCC = prev.defaultCC
  267. result.dynlib = prev.dynlib
  268. result.notes = c.config.notes
  269. result.warningAsErrors = c.config.warningAsErrors
  270. result.features = c.features
  271. c.optionStack.add(result)
  272. proc popOptionEntry*(c: PContext) =
  273. c.config.options = c.optionStack[^1].options
  274. c.config.notes = c.optionStack[^1].notes
  275. c.config.warningAsErrors = c.optionStack[^1].warningAsErrors
  276. c.features = c.optionStack[^1].features
  277. c.optionStack.setLen(c.optionStack.len - 1)
  278. proc newContext*(graph: ModuleGraph; module: PSym): PContext =
  279. new(result)
  280. result.optionStack = @[newOptionEntry(graph.config)]
  281. result.libs = @[]
  282. result.module = module
  283. result.friendModules = @[module]
  284. result.converters = @[]
  285. result.patterns = @[]
  286. result.includedFiles = initIntSet()
  287. result.pureEnumFields = initStrTable()
  288. result.userPragmas = initStrTable()
  289. result.generics = @[]
  290. result.unknownIdents = initIntSet()
  291. result.cache = graph.cache
  292. result.graph = graph
  293. result.signatures = initStrTable()
  294. result.features = graph.config.features
  295. if graph.config.symbolFiles != disabledSf:
  296. let id = module.position
  297. assert graph.packed[id].status in {undefined, outdated}
  298. graph.packed[id].status = storing
  299. graph.packed[id].module = module
  300. initEncoder graph, module
  301. template packedRepr*(c): untyped = c.graph.packed[c.module.position].fromDisk
  302. template encoder*(c): untyped = c.graph.encoders[c.module.position]
  303. proc addIncludeFileDep*(c: PContext; f: FileIndex) =
  304. if c.config.symbolFiles != disabledSf:
  305. addIncludeFileDep(c.encoder, c.packedRepr, f)
  306. proc addImportFileDep*(c: PContext; f: FileIndex) =
  307. if c.config.symbolFiles != disabledSf:
  308. addImportFileDep(c.encoder, c.packedRepr, f)
  309. proc addPragmaComputation*(c: PContext; n: PNode) =
  310. if c.config.symbolFiles != disabledSf:
  311. addPragmaComputation(c.encoder, c.packedRepr, n)
  312. proc inclSym(sq: var seq[PSym], s: PSym): bool =
  313. for i in 0..<sq.len:
  314. if sq[i].id == s.id: return false
  315. sq.add s
  316. result = true
  317. proc addConverter*(c: PContext, conv: LazySym) =
  318. assert conv.sym != nil
  319. if inclSym(c.converters, conv.sym):
  320. add(c.graph.ifaces[c.module.position].converters, conv)
  321. proc addConverterDef*(c: PContext, conv: LazySym) =
  322. addConverter(c, conv)
  323. if c.config.symbolFiles != disabledSf:
  324. addConverter(c.encoder, c.packedRepr, conv.sym)
  325. proc addPureEnum*(c: PContext, e: LazySym) =
  326. assert e.sym != nil
  327. add(c.graph.ifaces[c.module.position].pureEnums, e)
  328. if c.config.symbolFiles != disabledSf:
  329. addPureEnum(c.encoder, c.packedRepr, e.sym)
  330. proc addPattern*(c: PContext, p: LazySym) =
  331. assert p.sym != nil
  332. if inclSym(c.patterns, p.sym):
  333. add(c.graph.ifaces[c.module.position].patterns, p)
  334. if c.config.symbolFiles != disabledSf:
  335. addTrmacro(c.encoder, c.packedRepr, p.sym)
  336. proc exportSym*(c: PContext; s: PSym) =
  337. strTableAdds(c.graph, c.module, s)
  338. if c.config.symbolFiles != disabledSf:
  339. addExported(c.encoder, c.packedRepr, s)
  340. proc reexportSym*(c: PContext; s: PSym) =
  341. strTableAdds(c.graph, c.module, s)
  342. if c.config.symbolFiles != disabledSf:
  343. addReexport(c.encoder, c.packedRepr, s)
  344. proc newLib*(kind: TLibKind): PLib =
  345. new(result)
  346. result.kind = kind #result.syms = initObjectSet()
  347. proc addToLib*(lib: PLib, sym: PSym) =
  348. #if sym.annex != nil and not isGenericRoutine(sym):
  349. # LocalError(sym.info, errInvalidPragma)
  350. sym.annex = lib
  351. proc newTypeS*(kind: TTypeKind, c: PContext, sons: seq[PType] = @[]): PType =
  352. result = newType(kind, nextTypeId(c.idgen), getCurrOwner(c), sons = sons)
  353. proc makePtrType*(owner: PSym, baseType: PType; idgen: IdGenerator): PType =
  354. result = newType(tyPtr, nextTypeId(idgen), owner)
  355. addSonSkipIntLit(result, baseType, idgen)
  356. proc makePtrType*(c: PContext, baseType: PType): PType =
  357. makePtrType(getCurrOwner(c), baseType, c.idgen)
  358. proc makeTypeWithModifier*(c: PContext,
  359. modifier: TTypeKind,
  360. baseType: PType): PType =
  361. assert modifier in {tyVar, tyLent, tyPtr, tyRef, tyStatic, tyTypeDesc}
  362. if modifier in {tyVar, tyLent, tyTypeDesc} and baseType.kind == modifier:
  363. result = baseType
  364. else:
  365. result = newTypeS(modifier, c)
  366. addSonSkipIntLit(result, baseType, c.idgen)
  367. proc makeVarType*(c: PContext, baseType: PType; kind = tyVar): PType =
  368. if baseType.kind == kind:
  369. result = baseType
  370. else:
  371. result = newTypeS(kind, c)
  372. addSonSkipIntLit(result, baseType, c.idgen)
  373. proc makeVarType*(owner: PSym, baseType: PType; idgen: IdGenerator; kind = tyVar): PType =
  374. if baseType.kind == kind:
  375. result = baseType
  376. else:
  377. result = newType(kind, nextTypeId(idgen), owner)
  378. addSonSkipIntLit(result, baseType, idgen)
  379. proc makeTypeSymNode*(c: PContext, typ: PType, info: TLineInfo): PNode =
  380. let typedesc = newTypeS(tyTypeDesc, c)
  381. incl typedesc.flags, tfCheckedForDestructor
  382. internalAssert(c.config, typ != nil)
  383. typedesc.addSonSkipIntLit(typ, c.idgen)
  384. let sym = newSym(skType, c.cache.idAnon, c.idgen, getCurrOwner(c), info,
  385. c.config.options).linkTo(typedesc)
  386. result = newSymNode(sym, info)
  387. proc makeTypeFromExpr*(c: PContext, n: PNode): PType =
  388. result = newTypeS(tyFromExpr, c)
  389. assert n != nil
  390. result.n = n
  391. proc newTypeWithSons*(owner: PSym, kind: TTypeKind, sons: seq[PType];
  392. idgen: IdGenerator): PType =
  393. result = newType(kind, nextTypeId(idgen), owner, sons = sons)
  394. proc newTypeWithSons*(c: PContext, kind: TTypeKind,
  395. sons: seq[PType]): PType =
  396. result = newType(kind, nextTypeId(c.idgen), getCurrOwner(c), sons = sons)
  397. proc newTypeWithSons*(c: PContext, kind: TTypeKind,
  398. parent: PType): PType =
  399. result = newType(kind, nextTypeId(c.idgen), getCurrOwner(c), parent = parent)
  400. proc makeStaticExpr*(c: PContext, n: PNode): PNode =
  401. result = newNodeI(nkStaticExpr, n.info)
  402. result.sons = @[n]
  403. result.typ = if n.typ != nil and n.typ.kind == tyStatic: n.typ
  404. else: newTypeWithSons(c, tyStatic, @[n.typ])
  405. proc makeAndType*(c: PContext, t1, t2: PType): PType =
  406. result = newTypeS(tyAnd, c, sons = @[t1, t2])
  407. propagateToOwner(result, t1)
  408. propagateToOwner(result, t2)
  409. result.flags.incl((t1.flags + t2.flags) * {tfHasStatic})
  410. result.flags.incl tfHasMeta
  411. proc makeOrType*(c: PContext, t1, t2: PType): PType =
  412. if t1.kind != tyOr and t2.kind != tyOr:
  413. result = newTypeS(tyOr, c, sons = @[t1, t2])
  414. else:
  415. result = newTypeS(tyOr, c)
  416. template addOr(t1) =
  417. if t1.kind == tyOr:
  418. for x in t1: result.rawAddSon x
  419. else:
  420. result.rawAddSon t1
  421. addOr(t1)
  422. addOr(t2)
  423. propagateToOwner(result, t1)
  424. propagateToOwner(result, t2)
  425. result.flags.incl((t1.flags + t2.flags) * {tfHasStatic})
  426. result.flags.incl tfHasMeta
  427. proc makeNotType*(c: PContext, t1: PType): PType =
  428. result = newTypeS(tyNot, c, sons = @[t1])
  429. propagateToOwner(result, t1)
  430. result.flags.incl(t1.flags * {tfHasStatic})
  431. result.flags.incl tfHasMeta
  432. proc nMinusOne(c: PContext; n: PNode): PNode =
  433. result = newTreeI(nkCall, n.info, newSymNode(getSysMagic(c.graph, n.info, "pred", mPred)), n)
  434. # Remember to fix the procs below this one when you make changes!
  435. proc makeRangeWithStaticExpr*(c: PContext, n: PNode): PType =
  436. let intType = getSysType(c.graph, n.info, tyInt)
  437. result = newTypeS(tyRange, c, sons = @[intType])
  438. if n.typ != nil and n.typ.n == nil:
  439. result.flags.incl tfUnresolved
  440. result.n = newTreeI(nkRange, n.info, newIntTypeNode(0, intType),
  441. makeStaticExpr(c, nMinusOne(c, n)))
  442. template rangeHasUnresolvedStatic*(t: PType): bool =
  443. tfUnresolved in t.flags
  444. proc errorType*(c: PContext): PType =
  445. ## creates a type representing an error state
  446. result = newTypeS(tyError, c)
  447. result.flags.incl tfCheckedForDestructor
  448. proc errorNode*(c: PContext, n: PNode): PNode =
  449. result = newNodeI(nkEmpty, n.info)
  450. result.typ = errorType(c)
  451. # These mimic localError
  452. template localErrorNode*(c: PContext, n: PNode, info: TLineInfo, msg: TMsgKind, arg: string): PNode =
  453. liMessage(c.config, info, msg, arg, doNothing, instLoc())
  454. errorNode(c, n)
  455. template localErrorNode*(c: PContext, n: PNode, info: TLineInfo, arg: string): PNode =
  456. liMessage(c.config, info, errGenerated, arg, doNothing, instLoc())
  457. errorNode(c, n)
  458. template localErrorNode*(c: PContext, n: PNode, msg: TMsgKind, arg: string): PNode =
  459. let n2 = n
  460. liMessage(c.config, n2.info, msg, arg, doNothing, instLoc())
  461. errorNode(c, n2)
  462. template localErrorNode*(c: PContext, n: PNode, arg: string): PNode =
  463. let n2 = n
  464. liMessage(c.config, n2.info, errGenerated, arg, doNothing, instLoc())
  465. errorNode(c, n2)
  466. proc fillTypeS*(dest: PType, kind: TTypeKind, c: PContext) =
  467. dest.kind = kind
  468. dest.owner = getCurrOwner(c)
  469. dest.size = - 1
  470. proc makeRangeType*(c: PContext; first, last: BiggestInt;
  471. info: TLineInfo; intType: PType = nil): PType =
  472. let intType = if intType != nil: intType else: getSysType(c.graph, info, tyInt)
  473. var n = newNodeI(nkRange, info)
  474. n.add newIntTypeNode(first, intType)
  475. n.add newIntTypeNode(last, intType)
  476. result = newTypeS(tyRange, c)
  477. result.n = n
  478. addSonSkipIntLit(result, intType, c.idgen) # basetype of range
  479. proc isSelf*(t: PType): bool {.inline.} =
  480. ## Is this the magical 'Self' type from concepts?
  481. t.kind == tyTypeDesc and tfPacked in t.flags
  482. proc makeTypeDesc*(c: PContext, typ: PType): PType =
  483. if typ.kind == tyTypeDesc and not isSelf(typ):
  484. result = typ
  485. else:
  486. result = newTypeS(tyTypeDesc, c)
  487. incl result.flags, tfCheckedForDestructor
  488. result.addSonSkipIntLit(typ, c.idgen)
  489. proc symFromType*(c: PContext; t: PType, info: TLineInfo): PSym =
  490. if t.sym != nil: return t.sym
  491. result = newSym(skType, getIdent(c.cache, "AnonType"), c.idgen, t.owner, info)
  492. result.flags.incl sfAnon
  493. result.typ = t
  494. proc symNodeFromType*(c: PContext, t: PType, info: TLineInfo): PNode =
  495. result = newSymNode(symFromType(c, t, info), info)
  496. result.typ = makeTypeDesc(c, t)
  497. proc markIndirect*(c: PContext, s: PSym) {.inline.} =
  498. if s.kind in {skProc, skFunc, skConverter, skMethod, skIterator}:
  499. incl(s.flags, sfAddrTaken)
  500. # XXX add to 'c' for global analysis
  501. proc illFormedAst*(n: PNode; conf: ConfigRef) =
  502. globalError(conf, n.info, errIllFormedAstX, renderTree(n, {renderNoComments}))
  503. proc illFormedAstLocal*(n: PNode; conf: ConfigRef) =
  504. localError(conf, n.info, errIllFormedAstX, renderTree(n, {renderNoComments}))
  505. proc checkSonsLen*(n: PNode, length: int; conf: ConfigRef) =
  506. if n.len != length: illFormedAst(n, conf)
  507. proc checkMinSonsLen*(n: PNode, length: int; conf: ConfigRef) =
  508. if n.len < length: illFormedAst(n, conf)
  509. proc isTopLevel*(c: PContext): bool {.inline.} =
  510. result = c.currentScope.depthLevel <= 2
  511. proc isTopLevelInsideDeclaration*(c: PContext, sym: PSym): bool {.inline.} =
  512. # for routeKinds the scope isn't closed yet:
  513. c.currentScope.depthLevel <= 2 + ord(sym.kind in routineKinds)
  514. proc pushCaseContext*(c: PContext, caseNode: PNode) =
  515. c.p.caseContext.add((caseNode, 0))
  516. proc popCaseContext*(c: PContext) =
  517. discard pop(c.p.caseContext)
  518. proc setCaseContextIdx*(c: PContext, idx: int) =
  519. c.p.caseContext[^1].idx = idx
  520. template addExport*(c: PContext; s: PSym) =
  521. ## convenience to export a symbol from the current module
  522. addExport(c.graph, c.module, s)
  523. proc storeRodNode*(c: PContext, n: PNode) =
  524. if c.config.symbolFiles != disabledSf:
  525. toPackedNodeTopLevel(n, c.encoder, c.packedRepr)
  526. proc addToGenericProcCache*(c: PContext; s: PSym; inst: PInstantiation) =
  527. c.graph.procInstCache.mgetOrPut(s.itemId, @[]).add LazyInstantiation(module: c.module.position, inst: inst)
  528. if c.config.symbolFiles != disabledSf:
  529. storeInstantiation(c.encoder, c.packedRepr, s, inst)
  530. proc addToGenericCache*(c: PContext; s: PSym; inst: PType) =
  531. c.graph.typeInstCache.mgetOrPut(s.itemId, @[]).add LazyType(typ: inst)
  532. if c.config.symbolFiles != disabledSf:
  533. storeTypeInst(c.encoder, c.packedRepr, s, inst)
  534. proc sealRodFile*(c: PContext) =
  535. if c.config.symbolFiles != disabledSf:
  536. if c.graph.vm != nil:
  537. for (m, n) in PCtx(c.graph.vm).vmstateDiff:
  538. if m == c.module:
  539. addPragmaComputation(c, n)
  540. c.idgen.sealed = true # no further additions are allowed
  541. proc rememberExpansion*(c: PContext; info: TLineInfo; expandedSym: PSym) =
  542. ## Templates and macros are very special in Nim; these have
  543. ## inlining semantics so after semantic checking they leave no trace
  544. ## in the sem'checked AST. This is very bad for IDE-like tooling
  545. ## ("find all usages of this template" would not work). We need special
  546. ## logic to remember macro/template expansions. This is done here and
  547. ## delegated to the "rod" file mechanism.
  548. if c.config.symbolFiles != disabledSf:
  549. storeExpansion(c.encoder, c.packedRepr, info, expandedSym)