semdata.nim 23 KB

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