semdata.nim 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805
  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 std/[tables, intsets, sets, strutils]
  11. when defined(nimPreviewSlimSystem):
  12. import std/assertions
  13. import
  14. options, ast, msgs, idents, renderer,
  15. magicsys, vmdef, modulegraphs, lineinfos, pathutils, layeredtable,
  16. types, lowerings, trees, parampatterns
  17. import ic / ic
  18. type
  19. TOptionEntry* = object # entries to put on a stack for pragma parsing
  20. options*: TOptions
  21. defaultCC*: TCallingConvention
  22. dynlib*: PLib
  23. notes*: TNoteKinds
  24. features*: set[Feature]
  25. otherPragmas*: PNode # every pragma can be pushed
  26. warningAsErrors*: TNoteKinds
  27. POptionEntry* = ref TOptionEntry
  28. PProcCon* = ref TProcCon
  29. TProcCon* {.acyclic.} = object # procedure context; also used for top-level
  30. # statements
  31. owner*: PSym # the symbol this context belongs to
  32. resultSym*: PSym # the result symbol (if we are in a proc)
  33. nestedLoopCounter*: int # whether we are in a loop or not
  34. nestedBlockCounter*: int # whether we are in a block or not
  35. breakInLoop*: bool # whether we are in a loop without block
  36. next*: PProcCon # used for stacking procedure contexts
  37. mappingExists*: bool
  38. mapping*: Table[ItemId, PSym]
  39. caseContext*: seq[tuple[n: PNode, idx: int]]
  40. localBindStmts*: seq[PNode]
  41. TMatchedConcept* = object
  42. candidateType*: PType
  43. prev*: ptr TMatchedConcept
  44. depth*: int
  45. TInstantiationPair* = object
  46. genericSym*: PSym
  47. inst*: PInstantiation
  48. TExprFlag* = enum
  49. efLValue, efWantIterator, efWantIterable, efInTypeof,
  50. efNeedStatic,
  51. # Use this in contexts where a static value is mandatory
  52. efPreferStatic,
  53. # Use this in contexts where a static value could bring more
  54. # information, but it's not strictly mandatory. This may become
  55. # the default with implicit statics in the future.
  56. efPreferNilResult,
  57. # Use this if you want a certain result (e.g. static value),
  58. # but you don't want to trigger a hard error. For example,
  59. # you may be in position to supply a better error message
  60. # to the user.
  61. efWantStmt, efAllowStmt, efDetermineType, efExplain,
  62. efWantValue, efOperand, efNoSemCheck,
  63. efNoEvaluateGeneric, efInCall, efFromHlo, efNoSem2Check,
  64. efNoUndeclared, efIsDotCall, efCannotBeDotCall,
  65. # Use this if undeclared identifiers should not raise an error during
  66. # overload resolution.
  67. efTypeAllowed # typeAllowed will be called after
  68. efWantNoDefaults
  69. efIgnoreDefaults # var statements without initialization
  70. efAllowSymChoice # symchoice node should not be resolved
  71. TExprFlags* = set[TExprFlag]
  72. ImportMode* = enum
  73. importAll, importSet, importExcept
  74. ImportedModule* = object
  75. m*: PSym
  76. case mode*: ImportMode
  77. of importAll: discard
  78. of importSet:
  79. imported*: IntSet # of PIdent.id
  80. of importExcept:
  81. exceptSet*: IntSet # of PIdent.id
  82. PContext* = ref TContext
  83. TContext* = object of TPassContext # a context represents the module
  84. # that is currently being compiled
  85. enforceVoidContext*: PType
  86. # for `if cond: stmt else: foo`, `foo` will be evaluated under
  87. # enforceVoidContext != nil
  88. voidType*: PType # for typeof(stmt)
  89. module*: PSym # the module sym belonging to the context
  90. currentScope*: PScope # current scope
  91. moduleScope*: PScope # scope for modules
  92. imports*: seq[ImportedModule] # scope for all imported symbols
  93. topLevelScope*: PScope # scope for all top-level symbols
  94. p*: PProcCon # procedure context
  95. intTypeCache*: array[-5..32, PType] # cache some common integer types
  96. # to avoid type allocations
  97. nilTypeCache*: PType
  98. matchedConcept*: ptr TMatchedConcept # the current concept being matched
  99. friendModules*: seq[PSym] # friend modules; may access private data;
  100. # this is used so that generic instantiations
  101. # can access private object fields
  102. instCounter*: int # to prevent endless instantiations
  103. templInstCounter*: ref int # gives every template instantiation a unique id
  104. inGenericContext*: int # > 0 if we are in a generic type
  105. inStaticContext*: int # > 0 if we are inside a static: block
  106. inUnrolledContext*: int # > 0 if we are unrolling a loop
  107. compilesContextId*: int # > 0 if we are in a ``compiles`` magic
  108. compilesContextIdGenerator*: int
  109. inGenericInst*: int # > 0 if we are instantiating a generic
  110. converters*: seq[PSym]
  111. patterns*: seq[PSym] # sequence of pattern matchers
  112. optionStack*: seq[POptionEntry]
  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: LayeredIdTable, n: PNode): PNode
  127. semGenerateInstance*: proc (c: PContext, fn: PSym, pt: LayeredIdTable,
  128. info: TLineInfo): PSym
  129. instantiateOnlyProcType*: proc (c: PContext, pt: LayeredIdTable,
  130. prc: PSym, info: TLineInfo): PType
  131. # used by sigmatch for explicit generic instantiations
  132. fitDefaultNode*: proc (c: PContext, n: var PNode, expectedType: PType)
  133. includedFiles*: IntSet # used to detect recursive include files
  134. pureEnumFields*: TStrTable # pure enum fields that can be used unambiguously
  135. userPragmas*: TStrTable
  136. evalContext*: PEvalContext
  137. unknownIdents*: IntSet # ids of all unknown identifiers to prevent
  138. # naming it multiple times
  139. generics*: seq[TInstantiationPair] # pending list of instantiated generics to compile
  140. topStmts*: int # counts the number of encountered top level statements
  141. lastGenericIdx*: int # used for the generics stack
  142. hloLoopDetector*: int # used to prevent endless loops in the HLO
  143. inParallelStmt*: int
  144. instTypeBoundOp*: proc (c: PContext; dc: PSym; t: PType; info: TLineInfo;
  145. op: TTypeAttachedOp; col: int): PSym {.nimcall.}
  146. cache*: IdentCache
  147. graph*: ModuleGraph
  148. signatures*: TStrTable
  149. recursiveDep*: string
  150. suggestionsMade*: bool
  151. isAmbiguous*: bool # little hack
  152. features*: set[Feature]
  153. inTypeContext*, inConceptDecl*: int
  154. unusedImports*: seq[(PSym, TLineInfo)]
  155. exportIndirections*: HashSet[(int, int)] # (module.id, symbol.id)
  156. importModuleMap*: Table[int, int] # (module.id, module.id)
  157. lastTLineInfo*: TLineInfo
  158. sideEffects*: Table[int, seq[(TLineInfo, PSym)]] # symbol.id index
  159. inUncheckedAssignSection*: int
  160. importModuleLookup*: Table[int, seq[int]] # (module.ident.id, [module.id])
  161. skipTypes*: seq[PNode] # used to skip types between passes in type section. So far only used for inheritance, sets and generic bodies.
  162. inTypeofContext*: int
  163. semAsgnOpr*: proc (c: PContext; n: PNode; k: TNodeKind): PNode {.nimcall.}
  164. TBorrowState* = enum
  165. bsNone, bsReturnNotMatch, bsNoDistinct, bsGeneric, bsNotSupported, bsMatch
  166. template config*(c: PContext): ConfigRef = c.graph.config
  167. proc getIntLitType*(c: PContext; literal: PNode): PType =
  168. # we cache some common integer literal types for performance:
  169. let value = literal.intVal
  170. if value >= low(c.intTypeCache) and value <= high(c.intTypeCache):
  171. result = c.intTypeCache[value.int]
  172. if result == nil:
  173. let ti = getSysType(c.graph, literal.info, tyInt)
  174. result = copyType(ti, c.idgen, ti.owner)
  175. result.n = literal
  176. c.intTypeCache[value.int] = result
  177. else:
  178. let ti = getSysType(c.graph, literal.info, tyInt)
  179. result = copyType(ti, c.idgen, ti.owner)
  180. result.n = literal
  181. proc setIntLitType*(c: PContext; result: PNode) =
  182. let i = result.intVal
  183. case c.config.target.intSize
  184. of 8: result.typ() = getIntLitType(c, result)
  185. of 4:
  186. if i >= low(int32) and i <= high(int32):
  187. result.typ() = getIntLitType(c, result)
  188. else:
  189. result.typ() = getSysType(c.graph, result.info, tyInt64)
  190. of 2:
  191. if i >= low(int16) and i <= high(int16):
  192. result.typ() = getIntLitType(c, result)
  193. elif i >= low(int32) and i <= high(int32):
  194. result.typ() = getSysType(c.graph, result.info, tyInt32)
  195. else:
  196. result.typ() = getSysType(c.graph, result.info, tyInt64)
  197. of 1:
  198. # 8 bit CPUs are insane ...
  199. if i >= low(int8) and i <= high(int8):
  200. result.typ() = getIntLitType(c, result)
  201. elif i >= low(int16) and i <= high(int16):
  202. result.typ() = getSysType(c.graph, result.info, tyInt16)
  203. elif i >= low(int32) and i <= high(int32):
  204. result.typ() = getSysType(c.graph, result.info, tyInt32)
  205. else:
  206. result.typ() = getSysType(c.graph, result.info, tyInt64)
  207. else:
  208. internalError(c.config, result.info, "invalid int size")
  209. proc makeInstPair*(s: PSym, inst: PInstantiation): TInstantiationPair =
  210. result = TInstantiationPair(genericSym: s, inst: inst)
  211. proc filename*(c: PContext): string =
  212. # the module's filename
  213. result = toFilename(c.config, FileIndex c.module.position)
  214. proc scopeDepth*(c: PContext): int {.inline.} =
  215. result = if c.currentScope != nil: c.currentScope.depthLevel
  216. else: 0
  217. proc getCurrOwner*(c: PContext): PSym =
  218. # owner stack (used for initializing the
  219. # owner field of syms)
  220. # the documentation comment always gets
  221. # assigned to the current owner
  222. result = c.graph.owners[^1]
  223. proc pushOwner*(c: PContext; owner: PSym) =
  224. c.graph.owners.add(owner)
  225. proc popOwner*(c: PContext) =
  226. if c.graph.owners.len > 0: setLen(c.graph.owners, c.graph.owners.len - 1)
  227. else: internalError(c.config, "popOwner")
  228. proc lastOptionEntry*(c: PContext): POptionEntry =
  229. result = c.optionStack[^1]
  230. proc popProcCon*(c: PContext) {.inline.} = c.p = c.p.next
  231. proc put*(p: PProcCon; key, val: PSym) =
  232. if not p.mappingExists:
  233. p.mapping = initTable[ItemId, PSym]()
  234. p.mappingExists = true
  235. #echo "put into table ", key.info
  236. p.mapping[key.itemId] = val
  237. proc get*(p: PProcCon; key: PSym): PSym =
  238. if not p.mappingExists: return nil
  239. result = p.mapping.getOrDefault(key.itemId)
  240. proc getGenSym*(c: PContext; s: PSym): PSym =
  241. if sfGenSym notin s.flags: return s
  242. var it = c.p
  243. while it != nil:
  244. result = get(it, s)
  245. if result != nil:
  246. #echo "got from table ", result.name.s, " ", result.info
  247. return result
  248. it = it.next
  249. result = s
  250. proc considerGenSyms*(c: PContext; n: PNode) =
  251. if n == nil:
  252. discard "can happen for nkFormalParams/nkArgList"
  253. elif n.kind == nkSym:
  254. let s = getGenSym(c, n.sym)
  255. if n.sym != s:
  256. n.sym = s
  257. else:
  258. for i in 0..<n.safeLen:
  259. considerGenSyms(c, n[i])
  260. proc newOptionEntry*(conf: ConfigRef): POptionEntry =
  261. new(result)
  262. result.options = conf.options
  263. result.defaultCC = ccNimCall
  264. result.dynlib = nil
  265. result.notes = conf.notes
  266. result.warningAsErrors = conf.warningAsErrors
  267. proc pushOptionEntry*(c: PContext): POptionEntry =
  268. new(result)
  269. var prev = c.optionStack[^1]
  270. result.options = c.config.options
  271. result.defaultCC = prev.defaultCC
  272. result.dynlib = prev.dynlib
  273. result.notes = c.config.notes
  274. result.warningAsErrors = c.config.warningAsErrors
  275. result.features = c.features
  276. c.optionStack.add(result)
  277. proc popOptionEntry*(c: PContext) =
  278. c.config.options = c.optionStack[^1].options
  279. c.config.notes = c.optionStack[^1].notes
  280. c.config.warningAsErrors = c.optionStack[^1].warningAsErrors
  281. c.features = c.optionStack[^1].features
  282. c.optionStack.setLen(c.optionStack.len - 1)
  283. proc newContext*(graph: ModuleGraph; module: PSym): PContext =
  284. new(result)
  285. result.optionStack = @[newOptionEntry(graph.config)]
  286. result.libs = @[]
  287. result.module = module
  288. result.friendModules = @[module]
  289. result.converters = @[]
  290. result.patterns = @[]
  291. result.includedFiles = initIntSet()
  292. result.pureEnumFields = initStrTable()
  293. result.userPragmas = initStrTable()
  294. result.generics = @[]
  295. result.unknownIdents = initIntSet()
  296. result.cache = graph.cache
  297. result.graph = graph
  298. result.signatures = initStrTable()
  299. result.features = graph.config.features
  300. if graph.config.symbolFiles != disabledSf:
  301. let id = module.position
  302. if graph.config.cmd != cmdM:
  303. assert graph.packed[id].status in {undefined, outdated}
  304. graph.packed[id].status = storing
  305. graph.packed[id].module = module
  306. initEncoder graph, module
  307. template packedRepr*(c): untyped = c.graph.packed[c.module.position].fromDisk
  308. template encoder*(c): untyped = c.graph.encoders[c.module.position]
  309. proc addIncludeFileDep*(c: PContext; f: FileIndex) =
  310. if c.config.symbolFiles != disabledSf:
  311. addIncludeFileDep(c.encoder, c.packedRepr, f)
  312. proc addImportFileDep*(c: PContext; f: FileIndex) =
  313. if c.config.symbolFiles != disabledSf:
  314. addImportFileDep(c.encoder, c.packedRepr, f)
  315. proc addPragmaComputation*(c: PContext; n: PNode) =
  316. if c.config.symbolFiles != disabledSf:
  317. addPragmaComputation(c.encoder, c.packedRepr, n)
  318. proc inclSym(sq: var seq[PSym], s: PSym): bool =
  319. for i in 0..<sq.len:
  320. if sq[i].id == s.id: return false
  321. sq.add s
  322. result = true
  323. proc addConverter*(c: PContext, conv: LazySym) =
  324. assert conv.sym != nil
  325. if inclSym(c.converters, conv.sym):
  326. add(c.graph.ifaces[c.module.position].converters, conv)
  327. proc addConverterDef*(c: PContext, conv: LazySym) =
  328. addConverter(c, conv)
  329. if c.config.symbolFiles != disabledSf:
  330. addConverter(c.encoder, c.packedRepr, conv.sym)
  331. proc addPureEnum*(c: PContext, e: LazySym) =
  332. assert e.sym != nil
  333. add(c.graph.ifaces[c.module.position].pureEnums, e)
  334. if c.config.symbolFiles != disabledSf:
  335. addPureEnum(c.encoder, c.packedRepr, e.sym)
  336. proc addPattern*(c: PContext, p: LazySym) =
  337. assert p.sym != nil
  338. if inclSym(c.patterns, p.sym):
  339. add(c.graph.ifaces[c.module.position].patterns, p)
  340. if c.config.symbolFiles != disabledSf:
  341. addTrmacro(c.encoder, c.packedRepr, p.sym)
  342. proc exportSym*(c: PContext; s: PSym) =
  343. strTableAdds(c.graph, c.module, s)
  344. if c.config.symbolFiles != disabledSf:
  345. addExported(c.encoder, c.packedRepr, s)
  346. proc reexportSym*(c: PContext; s: PSym) =
  347. strTableAdds(c.graph, c.module, s)
  348. if c.config.symbolFiles != disabledSf:
  349. addReexport(c.encoder, c.packedRepr, s)
  350. proc newLib*(kind: TLibKind): PLib =
  351. new(result)
  352. result.kind = kind #result.syms = initObjectSet()
  353. proc addToLib*(lib: PLib, sym: PSym) =
  354. #if sym.annex != nil and not isGenericRoutine(sym):
  355. # LocalError(sym.info, errInvalidPragma)
  356. sym.annex = lib
  357. proc newTypeS*(kind: TTypeKind; c: PContext; son: sink PType = nil): PType =
  358. result = newType(kind, c.idgen, getCurrOwner(c), son = son)
  359. proc makePtrType*(owner: PSym, baseType: PType; idgen: IdGenerator): PType =
  360. result = newType(tyPtr, idgen, owner, skipIntLit(baseType, idgen))
  361. proc makePtrType*(c: PContext, baseType: PType): PType =
  362. makePtrType(getCurrOwner(c), baseType, c.idgen)
  363. proc makeTypeWithModifier*(c: PContext,
  364. modifier: TTypeKind,
  365. baseType: PType): PType =
  366. assert modifier in {tyVar, tyLent, tyPtr, tyRef, tyStatic, tyTypeDesc}
  367. if modifier in {tyVar, tyLent, tyTypeDesc} and baseType.kind == modifier:
  368. result = baseType
  369. else:
  370. result = newTypeS(modifier, c, skipIntLit(baseType, c.idgen))
  371. proc makeVarType*(c: PContext, baseType: PType; kind = tyVar): PType =
  372. if baseType.kind == kind:
  373. result = baseType
  374. else:
  375. result = newTypeS(kind, c, skipIntLit(baseType, c.idgen))
  376. proc makeTypeSymNode*(c: PContext, typ: PType, info: TLineInfo): PNode =
  377. let typedesc = newTypeS(tyTypeDesc, c)
  378. incl typedesc.flags, tfCheckedForDestructor
  379. internalAssert(c.config, typ != nil)
  380. typedesc.addSonSkipIntLit(typ, c.idgen)
  381. let sym = newSym(skType, c.cache.idAnon, c.idgen, getCurrOwner(c), info,
  382. c.config.options).linkTo(typedesc)
  383. result = newSymNode(sym, info)
  384. proc makeTypeFromExpr*(c: PContext, n: PNode): PType =
  385. result = newTypeS(tyFromExpr, c)
  386. assert n != nil
  387. result.n = n
  388. when false:
  389. proc newTypeWithSons*(owner: PSym, kind: TTypeKind, sons: seq[PType];
  390. idgen: IdGenerator): PType =
  391. result = newType(kind, idgen, owner, sons = sons)
  392. proc newTypeWithSons*(c: PContext, kind: TTypeKind,
  393. sons: seq[PType]): PType =
  394. result = newType(kind, c.idgen, getCurrOwner(c), sons = sons)
  395. proc makeStaticExpr*(c: PContext, n: PNode): PNode =
  396. result = newNodeI(nkStaticExpr, n.info)
  397. result.sons = @[n]
  398. result.typ() = if n.typ != nil and n.typ.kind == tyStatic: n.typ
  399. else: newTypeS(tyStatic, c, n.typ)
  400. proc makeAndType*(c: PContext, t1, t2: PType): PType =
  401. result = newTypeS(tyAnd, c)
  402. result.rawAddSon t1
  403. result.rawAddSon t2
  404. propagateToOwner(result, t1)
  405. propagateToOwner(result, t2)
  406. result.flags.incl((t1.flags + t2.flags) * {tfHasStatic})
  407. result.flags.incl tfHasMeta
  408. proc makeOrType*(c: PContext, t1, t2: PType): PType =
  409. if t1.kind != tyOr and t2.kind != tyOr:
  410. result = newTypeS(tyOr, c)
  411. result.rawAddSon t1
  412. result.rawAddSon t2
  413. else:
  414. result = newTypeS(tyOr, c)
  415. template addOr(t1) =
  416. if t1.kind == tyOr:
  417. for x in t1.kids: result.rawAddSon x
  418. else:
  419. result.rawAddSon t1
  420. addOr(t1)
  421. addOr(t2)
  422. propagateToOwner(result, t1)
  423. propagateToOwner(result, t2)
  424. result.flags.incl((t1.flags + t2.flags) * {tfHasStatic})
  425. result.flags.incl tfHasMeta
  426. proc makeNotType*(c: PContext, t1: PType): PType =
  427. result = newTypeS(tyNot, c, son = t1)
  428. propagateToOwner(result, t1)
  429. result.flags.incl(t1.flags * {tfHasStatic})
  430. result.flags.incl tfHasMeta
  431. proc nMinusOne(c: PContext; n: PNode): PNode =
  432. result = newTreeI(nkCall, n.info, newSymNode(getSysMagic(c.graph, n.info, "pred", mPred)), n)
  433. # Remember to fix the procs below this one when you make changes!
  434. proc makeRangeWithStaticExpr*(c: PContext, n: PNode): PType =
  435. let intType = getSysType(c.graph, n.info, tyInt)
  436. result = newTypeS(tyRange, c, son = intType)
  437. if n.typ != nil and n.typ.n == nil:
  438. result.flags.incl tfUnresolved
  439. result.n = newTreeI(nkRange, n.info, newIntTypeNode(0, intType),
  440. makeStaticExpr(c, nMinusOne(c, n)))
  441. template rangeHasUnresolvedStatic*(t: PType): bool =
  442. tfUnresolved in t.flags
  443. proc errorType*(c: PContext): PType =
  444. ## creates a type representing an error state
  445. result = newTypeS(tyError, c)
  446. result.flags.incl tfCheckedForDestructor
  447. proc errorNode*(c: PContext, n: PNode): PNode =
  448. result = newNodeI(nkEmpty, n.info)
  449. result.typ() = errorType(c)
  450. # These mimic localError
  451. template localErrorNode*(c: PContext, n: PNode, info: TLineInfo, msg: TMsgKind, arg: string): PNode =
  452. liMessage(c.config, info, msg, arg, doNothing, instLoc())
  453. errorNode(c, n)
  454. template localErrorNode*(c: PContext, n: PNode, info: TLineInfo, arg: string): PNode =
  455. liMessage(c.config, info, errGenerated, arg, doNothing, instLoc())
  456. errorNode(c, n)
  457. template localErrorNode*(c: PContext, n: PNode, msg: TMsgKind, arg: string): PNode =
  458. let n2 = n
  459. liMessage(c.config, n2.info, msg, arg, doNothing, instLoc())
  460. errorNode(c, n2)
  461. template localErrorNode*(c: PContext, n: PNode, arg: string): PNode =
  462. let n2 = n
  463. liMessage(c.config, n2.info, errGenerated, arg, doNothing, instLoc())
  464. errorNode(c, n2)
  465. when false:
  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, skipIntLit(typ, c.idgen))
  487. incl result.flags, tfCheckedForDestructor
  488. proc symFromType*(c: PContext; t: PType, info: TLineInfo): PSym =
  489. if t.sym != nil: return t.sym
  490. result = newSym(skType, getIdent(c.cache, "AnonType"), c.idgen, t.owner, info)
  491. result.flags.incl sfAnon
  492. result.typ = t
  493. proc symNodeFromType*(c: PContext, t: PType, info: TLineInfo): PNode =
  494. result = newSymNode(symFromType(c, t, info), info)
  495. result.typ() = makeTypeDesc(c, t)
  496. proc markIndirect*(c: PContext, s: PSym) {.inline.} =
  497. if s.kind in {skProc, skFunc, skConverter, skMethod, skIterator}:
  498. incl(s.flags, sfAddrTaken)
  499. # XXX add to 'c' for global analysis
  500. proc illFormedAst*(n: PNode; conf: ConfigRef) =
  501. globalError(conf, n.info, errIllFormedAstX, renderTree(n, {renderNoComments}))
  502. proc illFormedAstLocal*(n: PNode; conf: ConfigRef) =
  503. localError(conf, n.info, errIllFormedAstX, renderTree(n, {renderNoComments}))
  504. proc checkSonsLen*(n: PNode, length: int; conf: ConfigRef) =
  505. if n.len != length: illFormedAst(n, conf)
  506. proc checkMinSonsLen*(n: PNode, length: int; conf: ConfigRef) =
  507. if n.len < length: illFormedAst(n, conf)
  508. proc isTopLevel*(c: PContext): bool {.inline.} =
  509. result = c.currentScope.depthLevel <= 2
  510. proc isTopLevelInsideDeclaration*(c: PContext, sym: PSym): bool {.inline.} =
  511. # for routeKinds the scope isn't closed yet:
  512. c.currentScope.depthLevel <= 2 + ord(sym.kind in routineKinds)
  513. proc pushCaseContext*(c: PContext, caseNode: PNode) =
  514. c.p.caseContext.add((caseNode, 0))
  515. proc popCaseContext*(c: PContext) =
  516. discard pop(c.p.caseContext)
  517. proc setCaseContextIdx*(c: PContext, idx: int) =
  518. c.p.caseContext[^1].idx = idx
  519. template addExport*(c: PContext; s: PSym) =
  520. ## convenience to export a symbol from the current module
  521. addExport(c.graph, c.module, s)
  522. proc storeRodNode*(c: PContext, n: PNode) =
  523. if c.config.symbolFiles != disabledSf:
  524. toPackedNodeTopLevel(n, c.encoder, c.packedRepr)
  525. proc addToGenericProcCache*(c: PContext; s: PSym; inst: PInstantiation) =
  526. c.graph.procInstCache.mgetOrPut(s.itemId, @[]).add LazyInstantiation(module: c.module.position, inst: inst)
  527. if c.config.symbolFiles != disabledSf:
  528. storeInstantiation(c.encoder, c.packedRepr, s, inst)
  529. proc addToGenericCache*(c: PContext; s: PSym; inst: PType) =
  530. c.graph.typeInstCache.mgetOrPut(s.itemId, @[]).add LazyType(typ: inst)
  531. if c.config.symbolFiles != disabledSf:
  532. storeTypeInst(c.encoder, c.packedRepr, s, inst)
  533. proc sealRodFile*(c: PContext) =
  534. if c.config.symbolFiles != disabledSf:
  535. if c.graph.vm != nil:
  536. for (m, n) in PCtx(c.graph.vm).vmstateDiff:
  537. if m == c.module:
  538. addPragmaComputation(c, n)
  539. c.idgen.sealed = true # no further additions are allowed
  540. proc rememberExpansion*(c: PContext; info: TLineInfo; expandedSym: PSym) =
  541. ## Templates and macros are very special in Nim; these have
  542. ## inlining semantics so after semantic checking they leave no trace
  543. ## in the sem'checked AST. This is very bad for IDE-like tooling
  544. ## ("find all usages of this template" would not work). We need special
  545. ## logic to remember macro/template expansions. This is done here and
  546. ## delegated to the "rod" file mechanism.
  547. if c.config.symbolFiles != disabledSf:
  548. storeExpansion(c.encoder, c.packedRepr, info, expandedSym)
  549. const
  550. errVarForOutParamNeededX = "for a 'var' type a variable needs to be passed; but '$1' is immutable"
  551. errXStackEscape = "address of '$1' may not escape its stack frame"
  552. proc renderNotLValue*(n: PNode): string =
  553. result = $n
  554. let n = if n.kind == nkHiddenDeref: n[0] else: n
  555. if n.kind == nkHiddenCallConv and n.len > 1:
  556. result = $n[0] & "(" & result & ")"
  557. elif n.kind in {nkHiddenStdConv, nkHiddenSubConv} and n.len == 2:
  558. result = typeToString(n.typ.skipTypes(abstractVar)) & "(" & result & ")"
  559. proc isAssignable(c: PContext, n: PNode): TAssignableResult =
  560. result = parampatterns.isAssignable(c.p.owner, n)
  561. proc newHiddenAddrTaken(c: PContext, n: PNode, isOutParam: bool): PNode =
  562. if n.kind == nkHiddenDeref and not (c.config.backend == backendCpp or
  563. sfCompileToCpp in c.module.flags):
  564. checkSonsLen(n, 1, c.config)
  565. result = n[0]
  566. else:
  567. result = newNodeIT(nkHiddenAddr, n.info, makeVarType(c, n.typ))
  568. result.add n
  569. let aa = isAssignable(c, n)
  570. let sym = getRoot(n)
  571. if aa notin {arLValue, arLocalLValue}:
  572. if aa == arDiscriminant and c.inUncheckedAssignSection > 0:
  573. discard "allow access within a cast(unsafeAssign) section"
  574. elif strictDefs in c.features and aa == arAddressableConst and
  575. sym != nil and sym.kind == skLet and isOutParam:
  576. discard "allow let varaibles to be passed to out parameters"
  577. else:
  578. localError(c.config, n.info, errVarForOutParamNeededX % renderNotLValue(n))
  579. proc analyseIfAddressTaken(c: PContext, n: PNode, isOutParam: bool): PNode =
  580. result = n
  581. case n.kind
  582. of nkSym:
  583. # n.sym.typ can be nil in 'check' mode ...
  584. if n.sym.typ != nil and
  585. skipTypes(n.sym.typ, abstractInst-{tyTypeDesc}).kind notin {tyVar, tyLent}:
  586. incl(n.sym.flags, sfAddrTaken)
  587. result = newHiddenAddrTaken(c, n, isOutParam)
  588. of nkDotExpr:
  589. checkSonsLen(n, 2, c.config)
  590. if n[1].kind != nkSym:
  591. internalError(c.config, n.info, "analyseIfAddressTaken")
  592. return
  593. if skipTypes(n[1].sym.typ, abstractInst-{tyTypeDesc}).kind notin {tyVar, tyLent}:
  594. incl(n[1].sym.flags, sfAddrTaken)
  595. result = newHiddenAddrTaken(c, n, isOutParam)
  596. of nkBracketExpr:
  597. checkMinSonsLen(n, 1, c.config)
  598. if skipTypes(n[0].typ, abstractInst-{tyTypeDesc}).kind notin {tyVar, tyLent}:
  599. if n[0].kind == nkSym: incl(n[0].sym.flags, sfAddrTaken)
  600. result = newHiddenAddrTaken(c, n, isOutParam)
  601. else:
  602. result = newHiddenAddrTaken(c, n, isOutParam)
  603. proc analyseIfAddressTakenInCall*(c: PContext, n: PNode, isConverter = false) =
  604. checkMinSonsLen(n, 1, c.config)
  605. if n[0].typ == nil:
  606. # n[0] might be erroring node in nimsuggest
  607. return
  608. const
  609. FakeVarParams = {mNew, mNewFinalize, mInc, ast.mDec, mIncl, mExcl,
  610. mSetLengthStr, mSetLengthSeq, mAppendStrCh, mAppendStrStr, mSwap,
  611. mAppendSeqElem, mNewSeq, mShallowCopy, mDeepCopy, mMove, mWasMoved}
  612. template checkIfConverterCalled(c: PContext, n: PNode) =
  613. ## Checks if there is a converter call which wouldn't be checked otherwise
  614. # Call can sometimes be wrapped in a deref
  615. let node = if n.kind == nkHiddenDeref: n[0] else: n
  616. if node.kind == nkHiddenCallConv:
  617. analyseIfAddressTakenInCall(c, node, true)
  618. # get the real type of the callee
  619. # it may be a proc var with a generic alias type, so we skip over them
  620. var t = n[0].typ.skipTypes({tyGenericInst, tyAlias, tySink})
  621. if n[0].kind == nkSym and n[0].sym.magic in FakeVarParams:
  622. # BUGFIX: check for L-Value still needs to be done for the arguments!
  623. # note sometimes this is eval'ed twice so we check for nkHiddenAddr here:
  624. for i in 1..<n.len:
  625. if i < t.len and t[i] != nil and
  626. skipTypes(t[i], abstractInst-{tyTypeDesc}).kind in {tyVar}:
  627. let it = n[i]
  628. let aa = isAssignable(c, it)
  629. if aa notin {arLValue, arLocalLValue}:
  630. if it.kind != nkHiddenAddr:
  631. if aa == arDiscriminant and c.inUncheckedAssignSection > 0:
  632. discard "allow access within a cast(unsafeAssign) section"
  633. else:
  634. localError(c.config, it.info, errVarForOutParamNeededX % $it)
  635. # Make sure to still check arguments for converters
  636. c.checkIfConverterCalled(n[i])
  637. # bug #5113: disallow newSeq(result) where result is a 'var T':
  638. if n[0].sym.magic in {mNew, mNewFinalize, mNewSeq}:
  639. var arg = n[1] #.skipAddr
  640. if arg.kind == nkHiddenDeref: arg = arg[0]
  641. if arg.kind == nkSym and arg.sym.kind == skResult and
  642. arg.typ.skipTypes(abstractInst).kind in {tyVar, tyLent}:
  643. localError(c.config, n.info, errXStackEscape % renderTree(n[1], {renderNoComments}))
  644. return
  645. for i in 1..<n.len:
  646. let n = if n.kind == nkHiddenDeref: n[0] else: n
  647. c.checkIfConverterCalled(n[i])
  648. if i < t.len and
  649. skipTypes(t[i], abstractInst-{tyTypeDesc}).kind in {tyVar}:
  650. # Converters wrap var parameters in nkHiddenAddr but they haven't been analysed yet.
  651. # So we need to make sure we are checking them still when in a converter call
  652. if n[i].kind != nkHiddenAddr or isConverter:
  653. n[i] = analyseIfAddressTaken(c, n[i].skipAddr(), isOutParam(skipTypes(t[i], abstractInst-{tyTypeDesc})))
  654. proc replaceHookMagic*(c: PContext, n: PNode, kind: TTypeAttachedOp): PNode =
  655. ## Replaces builtin generic hooks with lifted hooks.
  656. case kind
  657. of attachedDestructor:
  658. result = n
  659. let t = n[1].typ.skipTypes(abstractVar)
  660. let op = getAttachedOp(c.graph, t, attachedDestructor)
  661. if op != nil:
  662. result[0] = newSymNode(op)
  663. if op.typ != nil and op.typ.len == 2 and op.typ.firstParamType.kind != tyVar:
  664. if n[1].kind == nkSym and n[1].sym.kind == skParam and
  665. n[1].typ.kind == tyVar:
  666. result[1] = genDeref(n[1])
  667. else:
  668. result[1] = skipAddr(n[1])
  669. of attachedTrace:
  670. result = n
  671. let t = n[1].typ.skipTypes(abstractVar)
  672. let op = getAttachedOp(c.graph, t, attachedTrace)
  673. if op != nil:
  674. result[0] = newSymNode(op)
  675. of attachedDup:
  676. result = n
  677. let t = n[1].typ.skipTypes(abstractVar)
  678. let op = getAttachedOp(c.graph, t, attachedDup)
  679. if op != nil:
  680. result[0] = newSymNode(op)
  681. if op.typ.len == 3:
  682. let boolLit = newIntLit(c.graph, n.info, 1)
  683. boolLit.typ() = getSysType(c.graph, n.info, tyBool)
  684. result.add boolLit
  685. of attachedWasMoved:
  686. result = n
  687. let t = n[1].typ.skipTypes(abstractVar)
  688. let op = getAttachedOp(c.graph, t, attachedWasMoved)
  689. if op != nil:
  690. result[0] = newSymNode(op)
  691. analyseIfAddressTakenInCall(c, result, false)
  692. of attachedSink:
  693. result = c.semAsgnOpr(c, n, nkSinkAsgn)
  694. of attachedAsgn:
  695. result = c.semAsgnOpr(c, n, nkAsgn)
  696. of attachedDeepCopy:
  697. result = n
  698. let t = n[1].typ.skipTypes(abstractVar)
  699. let op = getAttachedOp(c.graph, t, kind)
  700. if op != nil:
  701. result[0] = newSymNode(op)