semdata.nim 23 KB

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