ast.nim 82 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180
  1. #
  2. #
  3. # The Nim Compiler
  4. # (c) Copyright 2015 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. # abstract syntax tree + symbol table
  10. import
  11. lineinfos, hashes, options, ropes, idents, int128, tables
  12. from strutils import toLowerAscii
  13. when defined(nimPreviewSlimSystem):
  14. import std/assertions
  15. export int128
  16. type
  17. TCallingConvention* = enum
  18. ccNimCall = "nimcall" # nimcall, also the default
  19. ccStdCall = "stdcall" # procedure is stdcall
  20. ccCDecl = "cdecl" # cdecl
  21. ccSafeCall = "safecall" # safecall
  22. ccSysCall = "syscall" # system call
  23. ccInline = "inline" # proc should be inlined
  24. ccNoInline = "noinline" # proc should not be inlined
  25. ccFastCall = "fastcall" # fastcall (pass parameters in registers)
  26. ccThisCall = "thiscall" # thiscall (parameters are pushed right-to-left)
  27. ccClosure = "closure" # proc has a closure
  28. ccNoConvention = "noconv" # needed for generating proper C procs sometimes
  29. type
  30. TNodeKind* = enum # order is extremely important, because ranges are used
  31. # to check whether a node belongs to a certain class
  32. nkNone, # unknown node kind: indicates an error
  33. # Expressions:
  34. # Atoms:
  35. nkEmpty, # the node is empty
  36. nkIdent, # node is an identifier
  37. nkSym, # node is a symbol
  38. nkType, # node is used for its typ field
  39. nkCharLit, # a character literal ''
  40. nkIntLit, # an integer literal
  41. nkInt8Lit,
  42. nkInt16Lit,
  43. nkInt32Lit,
  44. nkInt64Lit,
  45. nkUIntLit, # an unsigned integer literal
  46. nkUInt8Lit,
  47. nkUInt16Lit,
  48. nkUInt32Lit,
  49. nkUInt64Lit,
  50. nkFloatLit, # a floating point literal
  51. nkFloat32Lit,
  52. nkFloat64Lit,
  53. nkFloat128Lit,
  54. nkStrLit, # a string literal ""
  55. nkRStrLit, # a raw string literal r""
  56. nkTripleStrLit, # a triple string literal """
  57. nkNilLit, # the nil literal
  58. # end of atoms
  59. nkComesFrom, # "comes from" template/macro information for
  60. # better stack trace generation
  61. nkDotCall, # used to temporarily flag a nkCall node;
  62. # this is used
  63. # for transforming ``s.len`` to ``len(s)``
  64. nkCommand, # a call like ``p 2, 4`` without parenthesis
  65. nkCall, # a call like p(x, y) or an operation like +(a, b)
  66. nkCallStrLit, # a call with a string literal
  67. # x"abc" has two sons: nkIdent, nkRStrLit
  68. # x"""abc""" has two sons: nkIdent, nkTripleStrLit
  69. nkInfix, # a call like (a + b)
  70. nkPrefix, # a call like !a
  71. nkPostfix, # something like a! (also used for visibility)
  72. nkHiddenCallConv, # an implicit type conversion via a type converter
  73. nkExprEqExpr, # a named parameter with equals: ''expr = expr''
  74. nkExprColonExpr, # a named parameter with colon: ''expr: expr''
  75. nkIdentDefs, # a definition like `a, b: typeDesc = expr`
  76. # either typeDesc or expr may be nil; used in
  77. # formal parameters, var statements, etc.
  78. nkVarTuple, # a ``var (a, b) = expr`` construct
  79. nkPar, # syntactic (); may be a tuple constructor
  80. nkObjConstr, # object constructor: T(a: 1, b: 2)
  81. nkCurly, # syntactic {}
  82. nkCurlyExpr, # an expression like a{i}
  83. nkBracket, # syntactic []
  84. nkBracketExpr, # an expression like a[i..j, k]
  85. nkPragmaExpr, # an expression like a{.pragmas.}
  86. nkRange, # an expression like i..j
  87. nkDotExpr, # a.b
  88. nkCheckedFieldExpr, # a.b, but b is a field that needs to be checked
  89. nkDerefExpr, # a^
  90. nkIfExpr, # if as an expression
  91. nkElifExpr,
  92. nkElseExpr,
  93. nkLambda, # lambda expression
  94. nkDo, # lambda block appering as trailing proc param
  95. nkAccQuoted, # `a` as a node
  96. nkTableConstr, # a table constructor {expr: expr}
  97. nkBind, # ``bind expr`` node
  98. nkClosedSymChoice, # symbol choice node; a list of nkSyms (closed)
  99. nkOpenSymChoice, # symbol choice node; a list of nkSyms (open)
  100. nkHiddenStdConv, # an implicit standard type conversion
  101. nkHiddenSubConv, # an implicit type conversion from a subtype
  102. # to a supertype
  103. nkConv, # a type conversion
  104. nkCast, # a type cast
  105. nkStaticExpr, # a static expr
  106. nkAddr, # a addr expression
  107. nkHiddenAddr, # implicit address operator
  108. nkHiddenDeref, # implicit ^ operator
  109. nkObjDownConv, # down conversion between object types
  110. nkObjUpConv, # up conversion between object types
  111. nkChckRangeF, # range check for floats
  112. nkChckRange64, # range check for 64 bit ints
  113. nkChckRange, # range check for ints
  114. nkStringToCString, # string to cstring
  115. nkCStringToString, # cstring to string
  116. # end of expressions
  117. nkAsgn, # a = b
  118. nkFastAsgn, # internal node for a fast ``a = b``
  119. # (no string copy)
  120. nkGenericParams, # generic parameters
  121. nkFormalParams, # formal parameters
  122. nkOfInherit, # inherited from symbol
  123. nkImportAs, # a 'as' b in an import statement
  124. nkProcDef, # a proc
  125. nkMethodDef, # a method
  126. nkConverterDef, # a converter
  127. nkMacroDef, # a macro
  128. nkTemplateDef, # a template
  129. nkIteratorDef, # an iterator
  130. nkOfBranch, # used inside case statements
  131. # for (cond, action)-pairs
  132. nkElifBranch, # used in if statements
  133. nkExceptBranch, # an except section
  134. nkElse, # an else part
  135. nkAsmStmt, # an assembler block
  136. nkPragma, # a pragma statement
  137. nkPragmaBlock, # a pragma with a block
  138. nkIfStmt, # an if statement
  139. nkWhenStmt, # a when expression or statement
  140. nkForStmt, # a for statement
  141. nkParForStmt, # a parallel for statement
  142. nkWhileStmt, # a while statement
  143. nkCaseStmt, # a case statement
  144. nkTypeSection, # a type section (consists of type definitions)
  145. nkVarSection, # a var section
  146. nkLetSection, # a let section
  147. nkConstSection, # a const section
  148. nkConstDef, # a const definition
  149. nkTypeDef, # a type definition
  150. nkYieldStmt, # the yield statement as a tree
  151. nkDefer, # the 'defer' statement
  152. nkTryStmt, # a try statement
  153. nkFinally, # a finally section
  154. nkRaiseStmt, # a raise statement
  155. nkReturnStmt, # a return statement
  156. nkBreakStmt, # a break statement
  157. nkContinueStmt, # a continue statement
  158. nkBlockStmt, # a block statement
  159. nkStaticStmt, # a static statement
  160. nkDiscardStmt, # a discard statement
  161. nkStmtList, # a list of statements
  162. nkImportStmt, # an import statement
  163. nkImportExceptStmt, # an import x except a statement
  164. nkExportStmt, # an export statement
  165. nkExportExceptStmt, # an 'export except' statement
  166. nkFromStmt, # a from * import statement
  167. nkIncludeStmt, # an include statement
  168. nkBindStmt, # a bind statement
  169. nkMixinStmt, # a mixin statement
  170. nkUsingStmt, # an using statement
  171. nkCommentStmt, # a comment statement
  172. nkStmtListExpr, # a statement list followed by an expr; this is used
  173. # to allow powerful multi-line templates
  174. nkBlockExpr, # a statement block ending in an expr; this is used
  175. # to allow powerful multi-line templates that open a
  176. # temporary scope
  177. nkStmtListType, # a statement list ending in a type; for macros
  178. nkBlockType, # a statement block ending in a type; for macros
  179. # types as syntactic trees:
  180. nkWith, # distinct with `foo`
  181. nkWithout, # distinct without `foo`
  182. nkTypeOfExpr, # type(1+2)
  183. nkObjectTy, # object body
  184. nkTupleTy, # tuple body
  185. nkTupleClassTy, # tuple type class
  186. nkTypeClassTy, # user-defined type class
  187. nkStaticTy, # ``static[T]``
  188. nkRecList, # list of object parts
  189. nkRecCase, # case section of object
  190. nkRecWhen, # when section of object
  191. nkRefTy, # ``ref T``
  192. nkPtrTy, # ``ptr T``
  193. nkVarTy, # ``var T``
  194. nkConstTy, # ``const T``
  195. nkOutTy, # ``out T``
  196. nkDistinctTy, # distinct type
  197. nkProcTy, # proc type
  198. nkIteratorTy, # iterator type
  199. nkSinkAsgn, # '=sink(x, y)'
  200. nkEnumTy, # enum body
  201. nkEnumFieldDef, # `ident = expr` in an enumeration
  202. nkArgList, # argument list
  203. nkPattern, # a special pattern; used for matching
  204. nkHiddenTryStmt, # a hidden try statement
  205. nkClosure, # (prc, env)-pair (internally used for code gen)
  206. nkGotoState, # used for the state machine (for iterators)
  207. nkState, # give a label to a code section (for iterators)
  208. nkBreakState, # special break statement for easier code generation
  209. nkFuncDef, # a func
  210. nkTupleConstr # a tuple constructor
  211. nkError # erroneous AST node
  212. nkModuleRef # for .rod file support: A (moduleId, itemId) pair
  213. nkReplayAction # for .rod file support: A replay action
  214. nkNilRodNode # for .rod file support: a 'nil' PNode
  215. TNodeKinds* = set[TNodeKind]
  216. type
  217. TSymFlag* = enum # 51 flags!
  218. sfUsed, # read access of sym (for warnings) or simply used
  219. sfExported, # symbol is exported from module
  220. sfFromGeneric, # symbol is instantiation of a generic; this is needed
  221. # for symbol file generation; such symbols should always
  222. # be written into the ROD file
  223. sfGlobal, # symbol is at global scope
  224. sfForward, # symbol is forward declared
  225. sfWasForwarded, # symbol had a forward declaration
  226. # (implies it's too dangerous to patch its type signature)
  227. sfImportc, # symbol is external; imported
  228. sfExportc, # symbol is exported (under a specified name)
  229. sfMangleCpp, # mangle as cpp (combines with `sfExportc`)
  230. sfVolatile, # variable is volatile
  231. sfRegister, # variable should be placed in a register
  232. sfPure, # object is "pure" that means it has no type-information
  233. # enum is "pure", its values need qualified access
  234. # variable is "pure"; it's an explicit "global"
  235. sfNoSideEffect, # proc has no side effects
  236. sfSideEffect, # proc may have side effects; cannot prove it has none
  237. sfMainModule, # module is the main module
  238. sfSystemModule, # module is the system module
  239. sfNoReturn, # proc never returns (an exit proc)
  240. sfAddrTaken, # the variable's address is taken (ex- or implicitly);
  241. # *OR*: a proc is indirectly called (used as first class)
  242. sfCompilerProc, # proc is a compiler proc, that is a C proc that is
  243. # needed for the code generator
  244. sfEscapes # param escapes
  245. # currently unimplemented
  246. sfDiscriminant, # field is a discriminant in a record/object
  247. sfRequiresInit, # field must be initialized during construction
  248. sfDeprecated, # symbol is deprecated
  249. sfExplain, # provide more diagnostics when this symbol is used
  250. sfError, # usage of symbol should trigger a compile-time error
  251. sfShadowed, # a symbol that was shadowed in some inner scope
  252. sfThread, # proc will run as a thread
  253. # variable is a thread variable
  254. sfCppNonPod, # tells compiler to treat such types as non-pod's, so that
  255. # `thread_local` is used instead of `__thread` for
  256. # {.threadvar.} + `--threads`. Only makes sense for importcpp types.
  257. # This has a performance impact so isn't set by default.
  258. sfCompileTime, # proc can be evaluated at compile time
  259. sfConstructor, # proc is a C++ constructor
  260. sfDispatcher, # copied method symbol is the dispatcher
  261. # deprecated and unused, except for the con
  262. sfBorrow, # proc is borrowed
  263. sfInfixCall, # symbol needs infix call syntax in target language;
  264. # for interfacing with C++, JS
  265. sfNamedParamCall, # symbol needs named parameter call syntax in target
  266. # language; for interfacing with Objective C
  267. sfDiscardable, # returned value may be discarded implicitly
  268. sfOverridden, # proc is overridden
  269. sfCallsite # A flag for template symbols to tell the
  270. # compiler it should use line information from
  271. # the calling side of the macro, not from the
  272. # implementation.
  273. sfGenSym # symbol is 'gensym'ed; do not add to symbol table
  274. sfNonReloadable # symbol will be left as-is when hot code reloading is on -
  275. # meaning that it won't be renamed and/or changed in any way
  276. sfGeneratedOp # proc is a generated '='; do not inject destructors in it
  277. # variable is generated closure environment; requires early
  278. # destruction for --newruntime.
  279. sfTemplateParam # symbol is a template parameter
  280. sfCursor # variable/field is a cursor, see RFC 177 for details
  281. sfInjectDestructors # whether the proc needs the 'injectdestructors' transformation
  282. sfNeverRaises # proc can never raise an exception, not even OverflowDefect
  283. # or out-of-memory
  284. sfSystemRaisesDefect # proc in the system can raise defects
  285. sfUsedInFinallyOrExcept # symbol is used inside an 'except' or 'finally'
  286. sfSingleUsedTemp # For temporaries that we know will only be used once
  287. sfNoalias # 'noalias' annotation, means C's 'restrict'
  288. # for templates and macros, means cannot be called
  289. # as a lone symbol (cannot use alias syntax)
  290. sfEffectsDelayed # an 'effectsDelayed' parameter
  291. sfGeneratedType # A anonymous generic type that is generated by the compiler for
  292. # objects that do not have generic parameters in case one of the
  293. # object fields has one.
  294. #
  295. # This is disallowed but can cause the typechecking to go into
  296. # an infinite loop, this flag is used as a sentinel to stop it.
  297. sfVirtual # proc is a C++ virtual function
  298. sfByCopy # param is marked as pass bycopy
  299. sfMember # proc is a C++ member of a type
  300. sfCodegenDecl # type, proc, global or proc param is marked as codegenDecl
  301. TSymFlags* = set[TSymFlag]
  302. const
  303. sfNoInit* = sfMainModule # don't generate code to init the variable
  304. sfAllUntyped* = sfVolatile # macro or template is immediately expanded \
  305. # in a generic context
  306. sfDirty* = sfPure
  307. # template is not hygienic (old styled template)
  308. # module, compiled from a dirty-buffer
  309. sfAnon* = sfDiscardable
  310. # symbol name that was generated by the compiler
  311. # the compiler will avoid printing such names
  312. # in user messages.
  313. sfNoForward* = sfRegister
  314. # forward declarations are not required (per module)
  315. sfReorder* = sfForward
  316. # reordering pass is enabled
  317. sfCompileToCpp* = sfInfixCall # compile the module as C++ code
  318. sfCompileToObjc* = sfNamedParamCall # compile the module as Objective-C code
  319. sfExperimental* = sfOverridden # module uses the .experimental switch
  320. sfGoto* = sfOverridden # var is used for 'goto' code generation
  321. sfWrittenTo* = sfBorrow # param is assigned to
  322. # currently unimplemented
  323. sfBase* = sfDiscriminant
  324. sfCustomPragma* = sfRegister # symbol is custom pragma template
  325. sfTemplateRedefinition* = sfExportc # symbol is a redefinition of an earlier template
  326. sfCppMember* = { sfVirtual, sfMember, sfConstructor } # proc is a C++ member, meaning it will be attached to the type definition
  327. const
  328. # getting ready for the future expr/stmt merge
  329. nkWhen* = nkWhenStmt
  330. nkWhenExpr* = nkWhenStmt
  331. nkEffectList* = nkArgList
  332. # hacks ahead: an nkEffectList is a node with 4 children:
  333. exceptionEffects* = 0 # exceptions at position 0
  334. requiresEffects* = 1 # 'requires' annotation
  335. ensuresEffects* = 2 # 'ensures' annotation
  336. tagEffects* = 3 # user defined tag ('gc', 'time' etc.)
  337. pragmasEffects* = 4 # not an effect, but a slot for pragmas in proc type
  338. forbiddenEffects* = 5 # list of illegal effects
  339. effectListLen* = 6 # list of effects list
  340. nkLastBlockStmts* = {nkRaiseStmt, nkReturnStmt, nkBreakStmt, nkContinueStmt}
  341. # these must be last statements in a block
  342. type
  343. TTypeKind* = enum # order is important!
  344. # Don't forget to change hti.nim if you make a change here
  345. # XXX put this into an include file to avoid this issue!
  346. # several types are no longer used (guess which), but a
  347. # spot in the sequence is kept for backwards compatibility
  348. # (apparently something with bootstrapping)
  349. # if you need to add a type, they can apparently be reused
  350. tyNone, tyBool, tyChar,
  351. tyEmpty, tyAlias, tyNil, tyUntyped, tyTyped, tyTypeDesc,
  352. tyGenericInvocation, # ``T[a, b]`` for types to invoke
  353. tyGenericBody, # ``T[a, b, body]`` last parameter is the body
  354. tyGenericInst, # ``T[a, b, realInstance]`` instantiated generic type
  355. # realInstance will be a concrete type like tyObject
  356. # unless this is an instance of a generic alias type.
  357. # then realInstance will be the tyGenericInst of the
  358. # completely (recursively) resolved alias.
  359. tyGenericParam, # ``a`` in the above patterns
  360. tyDistinct,
  361. tyEnum,
  362. tyOrdinal, # integer types (including enums and boolean)
  363. tyArray,
  364. tyObject,
  365. tyTuple,
  366. tySet,
  367. tyRange,
  368. tyPtr, tyRef,
  369. tyVar,
  370. tySequence,
  371. tyProc,
  372. tyPointer, tyOpenArray,
  373. tyString, tyCstring, tyForward,
  374. tyInt, tyInt8, tyInt16, tyInt32, tyInt64, # signed integers
  375. tyFloat, tyFloat32, tyFloat64, tyFloat128,
  376. tyUInt, tyUInt8, tyUInt16, tyUInt32, tyUInt64,
  377. tyOwned, tySink, tyLent,
  378. tyVarargs,
  379. tyUncheckedArray
  380. # An array with boundaries [0,+∞]
  381. tyProxy # used as errornous type (for idetools)
  382. tyBuiltInTypeClass
  383. # Type such as the catch-all object, tuple, seq, etc
  384. tyUserTypeClass
  385. # the body of a user-defined type class
  386. tyUserTypeClassInst
  387. # Instance of a parametric user-defined type class.
  388. # Structured similarly to tyGenericInst.
  389. # tyGenericInst represents concrete types, while
  390. # this is still a "generic param" that will bind types
  391. # and resolves them during sigmatch and instantiation.
  392. tyCompositeTypeClass
  393. # Type such as seq[Number]
  394. # The notes for tyUserTypeClassInst apply here as well
  395. # sons[0]: the original expression used by the user.
  396. # sons[1]: fully expanded and instantiated meta type
  397. # (potentially following aliases)
  398. tyInferred
  399. # In the initial state `base` stores a type class constraining
  400. # the types that can be inferred. After a candidate type is
  401. # selected, it's stored in `lastSon`. Between `base` and `lastSon`
  402. # there may be 0, 2 or more types that were also considered as
  403. # possible candidates in the inference process (i.e. lastSon will
  404. # be updated to store a type best conforming to all candidates)
  405. tyAnd, tyOr, tyNot
  406. # boolean type classes such as `string|int`,`not seq`,
  407. # `Sortable and Enumable`, etc
  408. tyAnything
  409. # a type class matching any type
  410. tyStatic
  411. # a value known at compile type (the underlying type is .base)
  412. tyFromExpr
  413. # This is a type representing an expression that depends
  414. # on generic parameters (the expression is stored in t.n)
  415. # It will be converted to a real type only during generic
  416. # instantiation and prior to this it has the potential to
  417. # be any type.
  418. tyConcept
  419. # new style concept.
  420. tyVoid
  421. # now different from tyEmpty, hurray!
  422. tyIterable
  423. static:
  424. # remind us when TTypeKind stops to fit in a single 64-bit word
  425. # assert TTypeKind.high.ord <= 63
  426. discard
  427. const
  428. tyPureObject* = tyTuple
  429. GcTypeKinds* = {tyRef, tySequence, tyString}
  430. tyError* = tyProxy # as an errornous node should match everything
  431. tyUnknown* = tyFromExpr
  432. tyUnknownTypes* = {tyError, tyFromExpr}
  433. tyTypeClasses* = {tyBuiltInTypeClass, tyCompositeTypeClass,
  434. tyUserTypeClass, tyUserTypeClassInst,
  435. tyAnd, tyOr, tyNot, tyAnything}
  436. tyMetaTypes* = {tyGenericParam, tyTypeDesc, tyUntyped} + tyTypeClasses
  437. tyUserTypeClasses* = {tyUserTypeClass, tyUserTypeClassInst}
  438. # consider renaming as `tyAbstractVarRange`
  439. abstractVarRange* = {tyGenericInst, tyRange, tyVar, tyDistinct, tyOrdinal,
  440. tyTypeDesc, tyAlias, tyInferred, tySink, tyOwned}
  441. abstractInst* = {tyGenericInst, tyDistinct, tyOrdinal, tyTypeDesc, tyAlias,
  442. tyInferred, tySink, tyOwned} # xxx what about tyStatic?
  443. type
  444. TTypeKinds* = set[TTypeKind]
  445. TNodeFlag* = enum
  446. nfNone,
  447. nfBase2, # nfBase10 is default, so not needed
  448. nfBase8,
  449. nfBase16,
  450. nfAllConst, # used to mark complex expressions constant; easy to get rid of
  451. # but unfortunately it has measurable impact for compilation
  452. # efficiency
  453. nfTransf, # node has been transformed
  454. nfNoRewrite # node should not be transformed anymore
  455. nfSem # node has been checked for semantics
  456. nfLL # node has gone through lambda lifting
  457. nfDotField # the call can use a dot operator
  458. nfDotSetter # the call can use a setter dot operarator
  459. nfExplicitCall # x.y() was used instead of x.y
  460. nfExprCall # this is an attempt to call a regular expression
  461. nfIsRef # this node is a 'ref' node; used for the VM
  462. nfIsPtr # this node is a 'ptr' node; used for the VM
  463. nfPreventCg # this node should be ignored by the codegen
  464. nfBlockArg # this a stmtlist appearing in a call (e.g. a do block)
  465. nfFromTemplate # a top-level node returned from a template
  466. nfDefaultParam # an automatically inserter default parameter
  467. nfDefaultRefsParam # a default param value references another parameter
  468. # the flag is applied to proc default values and to calls
  469. nfExecuteOnReload # A top-level statement that will be executed during reloads
  470. nfLastRead # this node is a last read
  471. nfFirstWrite # this node is a first write
  472. nfHasComment # node has a comment
  473. nfSkipFieldChecking # node skips field visable checking
  474. TNodeFlags* = set[TNodeFlag]
  475. TTypeFlag* = enum # keep below 32 for efficiency reasons (now: 47)
  476. tfVarargs, # procedure has C styled varargs
  477. # tyArray type represeting a varargs list
  478. tfNoSideEffect, # procedure type does not allow side effects
  479. tfFinal, # is the object final?
  480. tfInheritable, # is the object inheritable?
  481. tfHasOwned, # type contains an 'owned' type and must be moved
  482. tfEnumHasHoles, # enum cannot be mapped into a range
  483. tfShallow, # type can be shallow copied on assignment
  484. tfThread, # proc type is marked as ``thread``; alias for ``gcsafe``
  485. tfFromGeneric, # type is an instantiation of a generic; this is needed
  486. # because for instantiations of objects, structural
  487. # type equality has to be used
  488. tfUnresolved, # marks unresolved typedesc/static params: e.g.
  489. # proc foo(T: typedesc, list: seq[T]): var T
  490. # proc foo(L: static[int]): array[L, int]
  491. # can be attached to ranges to indicate that the range
  492. # can be attached to generic procs with free standing
  493. # type parameters: e.g. proc foo[T]()
  494. # depends on unresolved static params.
  495. tfResolved # marks a user type class, after it has been bound to a
  496. # concrete type (lastSon becomes the concrete type)
  497. tfRetType, # marks return types in proc (used to detect type classes
  498. # used as return types for return type inference)
  499. tfCapturesEnv, # whether proc really captures some environment
  500. tfByCopy, # pass object/tuple by copy (C backend)
  501. tfByRef, # pass object/tuple by reference (C backend)
  502. tfIterator, # type is really an iterator, not a tyProc
  503. tfPartial, # type is declared as 'partial'
  504. tfNotNil, # type cannot be 'nil'
  505. tfRequiresInit, # type constains a "not nil" constraint somewhere or
  506. # a `requiresInit` field, so the default zero init
  507. # is not appropriate
  508. tfNeedsFullInit, # object type marked with {.requiresInit.}
  509. # all fields must be initialized
  510. tfVarIsPtr, # 'var' type is translated like 'ptr' even in C++ mode
  511. tfHasMeta, # type contains "wildcard" sub-types such as generic params
  512. # or other type classes
  513. tfHasGCedMem, # type contains GC'ed memory
  514. tfPacked
  515. tfHasStatic
  516. tfGenericTypeParam
  517. tfImplicitTypeParam
  518. tfInferrableStatic
  519. tfConceptMatchedTypeSym
  520. tfExplicit # for typedescs, marks types explicitly prefixed with the
  521. # `type` operator (e.g. type int)
  522. tfWildcard # consider a proc like foo[T, I](x: Type[T, I])
  523. # T and I here can bind to both typedesc and static types
  524. # before this is determined, we'll consider them to be a
  525. # wildcard type.
  526. tfHasAsgn # type has overloaded assignment operator
  527. tfBorrowDot # distinct type borrows '.'
  528. tfTriggersCompileTime # uses the NimNode type which make the proc
  529. # implicitly '.compiletime'
  530. tfRefsAnonObj # used for 'ref object' and 'ptr object'
  531. tfCovariant # covariant generic param mimicking a ptr type
  532. tfWeakCovariant # covariant generic param mimicking a seq/array type
  533. tfContravariant # contravariant generic param
  534. tfCheckedForDestructor # type was checked for having a destructor.
  535. # If it has one, t.destructor is not nil.
  536. tfAcyclic # object type was annotated as .acyclic
  537. tfIncompleteStruct # treat this type as if it had sizeof(pointer)
  538. tfCompleteStruct
  539. # (for importc types); type is fully specified, allowing to compute
  540. # sizeof, alignof, offsetof at CT
  541. tfExplicitCallConv
  542. tfIsConstructor
  543. tfEffectSystemWorkaround
  544. tfIsOutParam
  545. tfSendable
  546. tfImplicitStatic
  547. TTypeFlags* = set[TTypeFlag]
  548. TSymKind* = enum # the different symbols (start with the prefix sk);
  549. # order is important for the documentation generator!
  550. skUnknown, # unknown symbol: used for parsing assembler blocks
  551. # and first phase symbol lookup in generics
  552. skConditional, # symbol for the preprocessor (may become obsolete)
  553. skDynLib, # symbol represents a dynamic library; this is used
  554. # internally; it does not exist in Nim code
  555. skParam, # a parameter
  556. skGenericParam, # a generic parameter; eq in ``proc x[eq=`==`]()``
  557. skTemp, # a temporary variable (introduced by compiler)
  558. skModule, # module identifier
  559. skType, # a type
  560. skVar, # a variable
  561. skLet, # a 'let' symbol
  562. skConst, # a constant
  563. skResult, # special 'result' variable
  564. skProc, # a proc
  565. skFunc, # a func
  566. skMethod, # a method
  567. skIterator, # an iterator
  568. skConverter, # a type converter
  569. skMacro, # a macro
  570. skTemplate, # a template; currently also misused for user-defined
  571. # pragmas
  572. skField, # a field in a record or object
  573. skEnumField, # an identifier in an enum
  574. skForVar, # a for loop variable
  575. skLabel, # a label (for block statement)
  576. skStub, # symbol is a stub and not yet loaded from the ROD
  577. # file (it is loaded on demand, which may
  578. # mean: never)
  579. skPackage, # symbol is a package (used for canonicalization)
  580. TSymKinds* = set[TSymKind]
  581. const
  582. routineKinds* = {skProc, skFunc, skMethod, skIterator,
  583. skConverter, skMacro, skTemplate}
  584. ExportableSymKinds* = {skVar, skLet, skConst, skType, skEnumField, skStub} + routineKinds
  585. tfUnion* = tfNoSideEffect
  586. tfGcSafe* = tfThread
  587. tfObjHasKids* = tfEnumHasHoles
  588. tfReturnsNew* = tfInheritable
  589. skError* = skUnknown
  590. var
  591. eqTypeFlags* = {tfIterator, tfNotNil, tfVarIsPtr, tfGcSafe, tfNoSideEffect, tfIsOutParam}
  592. ## type flags that are essential for type equality.
  593. ## This is now a variable because for emulation of version:1.0 we
  594. ## might exclude {tfGcSafe, tfNoSideEffect}.
  595. type
  596. TMagic* = enum # symbols that require compiler magic:
  597. mNone,
  598. mDefined, mDeclared, mDeclaredInScope, mCompiles, mArrGet, mArrPut, mAsgn,
  599. mLow, mHigh, mSizeOf, mAlignOf, mOffsetOf, mTypeTrait,
  600. mIs, mOf, mAddr, mType, mTypeOf,
  601. mPlugin, mEcho, mShallowCopy, mSlurp, mStaticExec, mStatic,
  602. mParseExprToAst, mParseStmtToAst, mExpandToAst, mQuoteAst,
  603. mInc, mDec, mOrd,
  604. mNew, mNewFinalize, mNewSeq, mNewSeqOfCap,
  605. mLengthOpenArray, mLengthStr, mLengthArray, mLengthSeq,
  606. mIncl, mExcl, mCard, mChr,
  607. mGCref, mGCunref,
  608. mAddI, mSubI, mMulI, mDivI, mModI,
  609. mSucc, mPred,
  610. mAddF64, mSubF64, mMulF64, mDivF64,
  611. mShrI, mShlI, mAshrI, mBitandI, mBitorI, mBitxorI,
  612. mMinI, mMaxI,
  613. mAddU, mSubU, mMulU, mDivU, mModU,
  614. mEqI, mLeI, mLtI,
  615. mEqF64, mLeF64, mLtF64,
  616. mLeU, mLtU,
  617. mEqEnum, mLeEnum, mLtEnum,
  618. mEqCh, mLeCh, mLtCh,
  619. mEqB, mLeB, mLtB,
  620. mEqRef, mLePtr, mLtPtr,
  621. mXor, mEqCString, mEqProc,
  622. mUnaryMinusI, mUnaryMinusI64, mAbsI, mNot,
  623. mUnaryPlusI, mBitnotI,
  624. mUnaryPlusF64, mUnaryMinusF64,
  625. mCharToStr, mBoolToStr,
  626. mIntToStr, mInt64ToStr, mFloatToStr, # for compiling nimStdlibVersion < 1.5.1 (not bootstrapping)
  627. mCStrToStr,
  628. mStrToStr, mEnumToStr,
  629. mAnd, mOr,
  630. mImplies, mIff, mExists, mForall, mOld,
  631. mEqStr, mLeStr, mLtStr,
  632. mEqSet, mLeSet, mLtSet, mMulSet, mPlusSet, mMinusSet,
  633. mConStrStr, mSlice,
  634. mDotDot, # this one is only necessary to give nice compile time warnings
  635. mFields, mFieldPairs, mOmpParFor,
  636. mAppendStrCh, mAppendStrStr, mAppendSeqElem,
  637. mInSet, mRepr, mExit,
  638. mSetLengthStr, mSetLengthSeq,
  639. mIsPartOf, mAstToStr, mParallel,
  640. mSwap, mIsNil, mArrToSeq, mOpenArrayToSeq,
  641. mNewString, mNewStringOfCap, mParseBiggestFloat,
  642. mMove, mEnsureMove, mWasMoved, mDup, mDestroy, mTrace,
  643. mDefault, mUnown, mFinished, mIsolate, mAccessEnv, mAccessTypeField, mReset,
  644. mArray, mOpenArray, mRange, mSet, mSeq, mVarargs,
  645. mRef, mPtr, mVar, mDistinct, mVoid, mTuple,
  646. mOrdinal, mIterableType,
  647. mInt, mInt8, mInt16, mInt32, mInt64,
  648. mUInt, mUInt8, mUInt16, mUInt32, mUInt64,
  649. mFloat, mFloat32, mFloat64, mFloat128,
  650. mBool, mChar, mString, mCstring,
  651. mPointer, mNil, mExpr, mStmt, mTypeDesc,
  652. mVoidType, mPNimrodNode, mSpawn, mDeepCopy,
  653. mIsMainModule, mCompileDate, mCompileTime, mProcCall,
  654. mCpuEndian, mHostOS, mHostCPU, mBuildOS, mBuildCPU, mAppType,
  655. mCompileOption, mCompileOptionArg,
  656. mNLen, mNChild, mNSetChild, mNAdd, mNAddMultiple, mNDel,
  657. mNKind, mNSymKind,
  658. mNccValue, mNccInc, mNcsAdd, mNcsIncl, mNcsLen, mNcsAt,
  659. mNctPut, mNctLen, mNctGet, mNctHasNext, mNctNext,
  660. mNIntVal, mNFloatVal, mNSymbol, mNIdent, mNGetType, mNStrVal, mNSetIntVal,
  661. mNSetFloatVal, mNSetSymbol, mNSetIdent, mNSetStrVal, mNLineInfo,
  662. mNNewNimNode, mNCopyNimNode, mNCopyNimTree, mStrToIdent, mNSigHash, mNSizeOf,
  663. mNBindSym, mNCallSite,
  664. mEqIdent, mEqNimrodNode, mSameNodeType, mGetImpl, mNGenSym,
  665. mNHint, mNWarning, mNError,
  666. mInstantiationInfo, mGetTypeInfo, mGetTypeInfoV2,
  667. mNimvm, mIntDefine, mStrDefine, mBoolDefine, mGenericDefine, mRunnableExamples,
  668. mException, mBuiltinType, mSymOwner, mUncheckedArray, mGetImplTransf,
  669. mSymIsInstantiationOf, mNodeId, mPrivateAccess, mZeroDefault
  670. const
  671. # things that we can evaluate safely at compile time, even if not asked for it:
  672. ctfeWhitelist* = {mNone, mSucc,
  673. mPred, mInc, mDec, mOrd, mLengthOpenArray,
  674. mLengthStr, mLengthArray, mLengthSeq,
  675. mArrGet, mArrPut, mAsgn, mDestroy,
  676. mIncl, mExcl, mCard, mChr,
  677. mAddI, mSubI, mMulI, mDivI, mModI,
  678. mAddF64, mSubF64, mMulF64, mDivF64,
  679. mShrI, mShlI, mBitandI, mBitorI, mBitxorI,
  680. mMinI, mMaxI,
  681. mAddU, mSubU, mMulU, mDivU, mModU,
  682. mEqI, mLeI, mLtI,
  683. mEqF64, mLeF64, mLtF64,
  684. mLeU, mLtU,
  685. mEqEnum, mLeEnum, mLtEnum,
  686. mEqCh, mLeCh, mLtCh,
  687. mEqB, mLeB, mLtB,
  688. mEqRef, mEqProc, mLePtr, mLtPtr, mEqCString, mXor,
  689. mUnaryMinusI, mUnaryMinusI64, mAbsI, mNot, mUnaryPlusI, mBitnotI,
  690. mUnaryPlusF64, mUnaryMinusF64,
  691. mCharToStr, mBoolToStr,
  692. mIntToStr, mInt64ToStr, mFloatToStr,
  693. mCStrToStr,
  694. mStrToStr, mEnumToStr,
  695. mAnd, mOr,
  696. mEqStr, mLeStr, mLtStr,
  697. mEqSet, mLeSet, mLtSet, mMulSet, mPlusSet, mMinusSet,
  698. mConStrStr, mAppendStrCh, mAppendStrStr, mAppendSeqElem,
  699. mInSet, mRepr, mOpenArrayToSeq}
  700. generatedMagics* = {mNone, mIsolate, mFinished, mOpenArrayToSeq}
  701. ## magics that are generated as normal procs in the backend
  702. type
  703. ItemId* = object
  704. module*: int32
  705. item*: int32
  706. proc `$`*(x: ItemId): string =
  707. "(module: " & $x.module & ", item: " & $x.item & ")"
  708. proc `==`*(a, b: ItemId): bool {.inline.} =
  709. a.item == b.item and a.module == b.module
  710. proc hash*(x: ItemId): Hash =
  711. var h: Hash = hash(x.module)
  712. h = h !& hash(x.item)
  713. result = !$h
  714. type
  715. TIdObj* {.acyclic.} = object of RootObj
  716. itemId*: ItemId
  717. PIdObj* = ref TIdObj
  718. PNode* = ref TNode
  719. TNodeSeq* = seq[PNode]
  720. PType* = ref TType
  721. PSym* = ref TSym
  722. TNode*{.final, acyclic.} = object # on a 32bit machine, this takes 32 bytes
  723. when defined(useNodeIds):
  724. id*: int
  725. typ*: PType
  726. info*: TLineInfo
  727. flags*: TNodeFlags
  728. case kind*: TNodeKind
  729. of nkCharLit..nkUInt64Lit:
  730. intVal*: BiggestInt
  731. of nkFloatLit..nkFloat128Lit:
  732. floatVal*: BiggestFloat
  733. of nkStrLit..nkTripleStrLit:
  734. strVal*: string
  735. of nkSym:
  736. sym*: PSym
  737. of nkIdent:
  738. ident*: PIdent
  739. else:
  740. sons*: TNodeSeq
  741. when defined(nimsuggest):
  742. endInfo*: TLineInfo
  743. TStrTable* = object # a table[PIdent] of PSym
  744. counter*: int
  745. data*: seq[PSym]
  746. # -------------- backend information -------------------------------
  747. TLocKind* = enum
  748. locNone, # no location
  749. locTemp, # temporary location
  750. locLocalVar, # location is a local variable
  751. locGlobalVar, # location is a global variable
  752. locParam, # location is a parameter
  753. locField, # location is a record field
  754. locExpr, # "location" is really an expression
  755. locProc, # location is a proc (an address of a procedure)
  756. locData, # location is a constant
  757. locCall, # location is a call expression
  758. locOther # location is something other
  759. TLocFlag* = enum
  760. lfIndirect, # backend introduced a pointer
  761. lfNoDeepCopy, # no need for a deep copy
  762. lfNoDecl, # do not declare it in C
  763. lfDynamicLib, # link symbol to dynamic library
  764. lfExportLib, # export symbol for dynamic library generation
  765. lfHeader, # include header file for symbol
  766. lfImportCompilerProc, # ``importc`` of a compilerproc
  767. lfSingleUse # no location yet and will only be used once
  768. lfEnforceDeref # a copyMem is required to dereference if this a
  769. # ptr array due to C array limitations.
  770. # See #1181, #6422, #11171
  771. lfPrepareForMutation # string location is about to be mutated (V2)
  772. TStorageLoc* = enum
  773. OnUnknown, # location is unknown (stack, heap or static)
  774. OnStatic, # in a static section
  775. OnStack, # location is on hardware stack
  776. OnHeap # location is on heap or global
  777. # (reference counting needed)
  778. TLocFlags* = set[TLocFlag]
  779. TLoc* = object
  780. k*: TLocKind # kind of location
  781. storage*: TStorageLoc
  782. flags*: TLocFlags # location's flags
  783. lode*: PNode # Node where the location came from; can be faked
  784. r*: Rope # rope value of location (code generators)
  785. # ---------------- end of backend information ------------------------------
  786. TLibKind* = enum
  787. libHeader, libDynamic
  788. TLib* = object # also misused for headers!
  789. # keep in sync with PackedLib
  790. kind*: TLibKind
  791. generated*: bool # needed for the backends:
  792. isOverridden*: bool
  793. name*: Rope
  794. path*: PNode # can be a string literal!
  795. CompilesId* = int ## id that is used for the caching logic within
  796. ## ``system.compiles``. See the seminst module.
  797. TInstantiation* = object
  798. sym*: PSym
  799. concreteTypes*: seq[PType]
  800. compilesId*: CompilesId
  801. PInstantiation* = ref TInstantiation
  802. TScope* {.acyclic.} = object
  803. depthLevel*: int
  804. symbols*: TStrTable
  805. parent*: PScope
  806. allowPrivateAccess*: seq[PSym] # # enable access to private fields
  807. PScope* = ref TScope
  808. PLib* = ref TLib
  809. TSym* {.acyclic.} = object of TIdObj # Keep in sync with PackedSym
  810. # proc and type instantiations are cached in the generic symbol
  811. case kind*: TSymKind
  812. of routineKinds:
  813. #procInstCache*: seq[PInstantiation]
  814. gcUnsafetyReason*: PSym # for better error messages regarding gcsafe
  815. transformedBody*: PNode # cached body after transf pass
  816. of skLet, skVar, skField, skForVar:
  817. guard*: PSym
  818. bitsize*: int
  819. alignment*: int # for alignment
  820. else: nil
  821. magic*: TMagic
  822. typ*: PType
  823. name*: PIdent
  824. info*: TLineInfo
  825. when defined(nimsuggest):
  826. endInfo*: TLineInfo
  827. owner*: PSym
  828. flags*: TSymFlags
  829. ast*: PNode # syntax tree of proc, iterator, etc.:
  830. # the whole proc including header; this is used
  831. # for easy generation of proper error messages
  832. # for variant record fields the discriminant
  833. # expression
  834. # for modules, it's a placeholder for compiler
  835. # generated code that will be appended to the
  836. # module after the sem pass (see appendToModule)
  837. options*: TOptions
  838. position*: int # used for many different things:
  839. # for enum fields its position;
  840. # for fields its offset
  841. # for parameters its position (starting with 0)
  842. # for a conditional:
  843. # 1 iff the symbol is defined, else 0
  844. # (or not in symbol table)
  845. # for modules, an unique index corresponding
  846. # to the module's fileIdx
  847. # for variables a slot index for the evaluator
  848. offset*: int32 # offset of record field
  849. disamb*: int32 # disambiguation number; the basic idea is that
  850. # `<procname>__<module>_<disamb>`
  851. loc*: TLoc
  852. annex*: PLib # additional fields (seldom used, so we use a
  853. # reference to another object to save space)
  854. when hasFFI:
  855. cname*: string # resolved C declaration name in importc decl, e.g.:
  856. # proc fun() {.importc: "$1aux".} => cname = funaux
  857. constraint*: PNode # additional constraints like 'lit|result'; also
  858. # misused for the codegenDecl and virtual pragmas in the hope
  859. # it won't cause problems
  860. # for skModule the string literal to output for
  861. # deprecated modules.
  862. instantiatedFrom*: PSym # for instances, the generic symbol where it came from.
  863. when defined(nimsuggest):
  864. allUsages*: seq[TLineInfo]
  865. TTypeSeq* = seq[PType]
  866. TTypeAttachedOp* = enum ## as usual, order is important here
  867. attachedWasMoved,
  868. attachedDestructor,
  869. attachedAsgn,
  870. attachedDup,
  871. attachedSink,
  872. attachedTrace,
  873. attachedDeepCopy
  874. TType* {.acyclic.} = object of TIdObj # \
  875. # types are identical iff they have the
  876. # same id; there may be multiple copies of a type
  877. # in memory!
  878. # Keep in sync with PackedType
  879. kind*: TTypeKind # kind of type
  880. callConv*: TCallingConvention # for procs
  881. flags*: TTypeFlags # flags of the type
  882. sons: TTypeSeq # base types, etc.
  883. n*: PNode # node for types:
  884. # for range types a nkRange node
  885. # for record types a nkRecord node
  886. # for enum types a list of symbols
  887. # if kind == tyInt: it is an 'int literal(x)' type
  888. # for procs and tyGenericBody, it's the
  889. # formal param list
  890. # for concepts, the concept body
  891. # else: unused
  892. owner*: PSym # the 'owner' of the type
  893. sym*: PSym # types have the sym associated with them
  894. # it is used for converting types to strings
  895. size*: BiggestInt # the size of the type in bytes
  896. # -1 means that the size is unkwown
  897. align*: int16 # the type's alignment requirements
  898. paddingAtEnd*: int16 #
  899. loc*: TLoc
  900. typeInst*: PType # for generic instantiations the tyGenericInst that led to this
  901. # type.
  902. uniqueId*: ItemId # due to a design mistake, we need to keep the real ID here as it
  903. # is required by the --incremental:on mode.
  904. TPair* = object
  905. key*, val*: RootRef
  906. TPairSeq* = seq[TPair]
  907. TIdPair* = object
  908. key*: PIdObj
  909. val*: RootRef
  910. TIdPairSeq* = seq[TIdPair]
  911. TIdTable* = object # the same as table[PIdent] of PObject
  912. counter*: int
  913. data*: TIdPairSeq
  914. TIdNodePair* = object
  915. key*: PIdObj
  916. val*: PNode
  917. TIdNodePairSeq* = seq[TIdNodePair]
  918. TIdNodeTable* = object # the same as table[PIdObj] of PNode
  919. counter*: int
  920. data*: TIdNodePairSeq
  921. TNodePair* = object
  922. h*: Hash # because it is expensive to compute!
  923. key*: PNode
  924. val*: int
  925. TNodePairSeq* = seq[TNodePair]
  926. TNodeTable* = object # the same as table[PNode] of int;
  927. # nodes are compared by structure!
  928. counter*: int
  929. data*: TNodePairSeq
  930. TObjectSeq* = seq[RootRef]
  931. TObjectSet* = object
  932. counter*: int
  933. data*: TObjectSeq
  934. TImplication* = enum
  935. impUnknown, impNo, impYes
  936. template nodeId(n: PNode): int = cast[int](n)
  937. type Gconfig = object
  938. # we put comments in a side channel to avoid increasing `sizeof(TNode)`, which
  939. # reduces memory usage given that `PNode` is the most allocated type by far.
  940. comments: Table[int, string] # nodeId => comment
  941. useIc*: bool
  942. var gconfig {.threadvar.}: Gconfig
  943. proc setUseIc*(useIc: bool) = gconfig.useIc = useIc
  944. proc comment*(n: PNode): string =
  945. if nfHasComment in n.flags and not gconfig.useIc:
  946. # IC doesn't track comments, see `packed_ast`, so this could fail
  947. result = gconfig.comments[n.nodeId]
  948. else:
  949. result = ""
  950. proc `comment=`*(n: PNode, a: string) =
  951. let id = n.nodeId
  952. if a.len > 0:
  953. # if needed, we could periodically cleanup gconfig.comments when its size increases,
  954. # to ensure only live nodes (and with nfHasComment) have an entry in gconfig.comments;
  955. # for compiling compiler, the waste is very small:
  956. # num calls to newNodeImpl: 14984160 (num of PNode allocations)
  957. # size of gconfig.comments: 33585
  958. # num of nodes with comments that were deleted and hence wasted: 3081
  959. n.flags.incl nfHasComment
  960. gconfig.comments[id] = a
  961. elif nfHasComment in n.flags:
  962. n.flags.excl nfHasComment
  963. gconfig.comments.del(id)
  964. # BUGFIX: a module is overloadable so that a proc can have the
  965. # same name as an imported module. This is necessary because of
  966. # the poor naming choices in the standard library.
  967. const
  968. OverloadableSyms* = {skProc, skFunc, skMethod, skIterator,
  969. skConverter, skModule, skTemplate, skMacro, skEnumField}
  970. GenericTypes*: TTypeKinds = {tyGenericInvocation, tyGenericBody,
  971. tyGenericParam}
  972. StructuralEquivTypes*: TTypeKinds = {tyNil, tyTuple, tyArray,
  973. tySet, tyRange, tyPtr, tyRef, tyVar, tyLent, tySequence, tyProc, tyOpenArray,
  974. tyVarargs}
  975. ConcreteTypes*: TTypeKinds = { # types of the expr that may occur in::
  976. # var x = expr
  977. tyBool, tyChar, tyEnum, tyArray, tyObject,
  978. tySet, tyTuple, tyRange, tyPtr, tyRef, tyVar, tyLent, tySequence, tyProc,
  979. tyPointer,
  980. tyOpenArray, tyString, tyCstring, tyInt..tyInt64, tyFloat..tyFloat128,
  981. tyUInt..tyUInt64}
  982. IntegralTypes* = {tyBool, tyChar, tyEnum, tyInt..tyInt64,
  983. tyFloat..tyFloat128, tyUInt..tyUInt64} # weird name because it contains tyFloat
  984. ConstantDataTypes*: TTypeKinds = {tyArray, tySet,
  985. tyTuple, tySequence}
  986. NilableTypes*: TTypeKinds = {tyPointer, tyCstring, tyRef, tyPtr,
  987. tyProc, tyError} # TODO
  988. PtrLikeKinds*: TTypeKinds = {tyPointer, tyPtr} # for VM
  989. PersistentNodeFlags*: TNodeFlags = {nfBase2, nfBase8, nfBase16,
  990. nfDotSetter, nfDotField,
  991. nfIsRef, nfIsPtr, nfPreventCg, nfLL,
  992. nfFromTemplate, nfDefaultRefsParam,
  993. nfExecuteOnReload, nfLastRead,
  994. nfFirstWrite, nfSkipFieldChecking}
  995. namePos* = 0
  996. patternPos* = 1 # empty except for term rewriting macros
  997. genericParamsPos* = 2
  998. paramsPos* = 3
  999. pragmasPos* = 4
  1000. miscPos* = 5 # used for undocumented and hacky stuff
  1001. bodyPos* = 6 # position of body; use rodread.getBody() instead!
  1002. resultPos* = 7
  1003. dispatcherPos* = 8
  1004. nfAllFieldsSet* = nfBase2
  1005. nkCallKinds* = {nkCall, nkInfix, nkPrefix, nkPostfix,
  1006. nkCommand, nkCallStrLit, nkHiddenCallConv}
  1007. nkIdentKinds* = {nkIdent, nkSym, nkAccQuoted, nkOpenSymChoice,
  1008. nkClosedSymChoice}
  1009. nkPragmaCallKinds* = {nkExprColonExpr, nkCall, nkCallStrLit}
  1010. nkLiterals* = {nkCharLit..nkTripleStrLit}
  1011. nkFloatLiterals* = {nkFloatLit..nkFloat128Lit}
  1012. nkLambdaKinds* = {nkLambda, nkDo}
  1013. declarativeDefs* = {nkProcDef, nkFuncDef, nkMethodDef, nkIteratorDef, nkConverterDef}
  1014. routineDefs* = declarativeDefs + {nkMacroDef, nkTemplateDef}
  1015. procDefs* = nkLambdaKinds + declarativeDefs
  1016. callableDefs* = nkLambdaKinds + routineDefs
  1017. nkSymChoices* = {nkClosedSymChoice, nkOpenSymChoice}
  1018. nkStrKinds* = {nkStrLit..nkTripleStrLit}
  1019. skLocalVars* = {skVar, skLet, skForVar, skParam, skResult}
  1020. skProcKinds* = {skProc, skFunc, skTemplate, skMacro, skIterator,
  1021. skMethod, skConverter}
  1022. defaultSize = -1
  1023. defaultAlignment = -1
  1024. defaultOffset* = -1
  1025. proc getPIdent*(a: PNode): PIdent {.inline.} =
  1026. ## Returns underlying `PIdent` for `{nkSym, nkIdent}`, or `nil`.
  1027. case a.kind
  1028. of nkSym: a.sym.name
  1029. of nkIdent: a.ident
  1030. of nkOpenSymChoice, nkClosedSymChoice: a.sons[0].sym.name
  1031. else: nil
  1032. const
  1033. moduleShift = when defined(cpu32): 20 else: 24
  1034. template id*(a: PIdObj): int =
  1035. let x = a
  1036. (x.itemId.module.int shl moduleShift) + x.itemId.item.int
  1037. type
  1038. IdGenerator* = ref object # unfortunately, we really need the 'shared mutable' aspect here.
  1039. module*: int32
  1040. symId*: int32
  1041. typeId*: int32
  1042. sealed*: bool
  1043. disambTable*: CountTable[PIdent]
  1044. const
  1045. PackageModuleId* = -3'i32
  1046. proc idGeneratorFromModule*(m: PSym): IdGenerator =
  1047. assert m.kind == skModule
  1048. result = IdGenerator(module: m.itemId.module, symId: m.itemId.item, typeId: 0, disambTable: initCountTable[PIdent]())
  1049. proc idGeneratorForPackage*(nextIdWillBe: int32): IdGenerator =
  1050. result = IdGenerator(module: PackageModuleId, symId: nextIdWillBe - 1'i32, typeId: 0, disambTable: initCountTable[PIdent]())
  1051. proc nextSymId*(x: IdGenerator): ItemId {.inline.} =
  1052. assert(not x.sealed)
  1053. inc x.symId
  1054. result = ItemId(module: x.module, item: x.symId)
  1055. proc nextTypeId*(x: IdGenerator): ItemId {.inline.} =
  1056. assert(not x.sealed)
  1057. inc x.typeId
  1058. result = ItemId(module: x.module, item: x.typeId)
  1059. when false:
  1060. proc nextId*(x: IdGenerator): ItemId {.inline.} =
  1061. inc x.item
  1062. result = x[]
  1063. when false:
  1064. proc storeBack*(dest: var IdGenerator; src: IdGenerator) {.inline.} =
  1065. assert dest.ItemId.module == src.ItemId.module
  1066. if dest.ItemId.item > src.ItemId.item:
  1067. echo dest.ItemId.item, " ", src.ItemId.item, " ", src.ItemId.module
  1068. assert dest.ItemId.item <= src.ItemId.item
  1069. dest = src
  1070. var ggDebug* {.deprecated.}: bool ## convenience switch for trying out things
  1071. proc isCallExpr*(n: PNode): bool =
  1072. result = n.kind in nkCallKinds
  1073. proc discardSons*(father: PNode)
  1074. type Indexable = PNode | PType
  1075. proc len*(n: Indexable): int {.inline.} =
  1076. result = n.sons.len
  1077. proc safeLen*(n: PNode): int {.inline.} =
  1078. ## works even for leaves.
  1079. if n.kind in {nkNone..nkNilLit}: result = 0
  1080. else: result = n.len
  1081. proc safeArrLen*(n: PNode): int {.inline.} =
  1082. ## works for array-like objects (strings passed as openArray in VM).
  1083. if n.kind in {nkStrLit..nkTripleStrLit}: result = n.strVal.len
  1084. elif n.kind in {nkNone..nkFloat128Lit}: result = 0
  1085. else: result = n.len
  1086. proc add*(father, son: Indexable) =
  1087. assert son != nil
  1088. father.sons.add(son)
  1089. proc addAllowNil*(father, son: Indexable) {.inline.} =
  1090. father.sons.add(son)
  1091. template `[]`*(n: Indexable, i: int): Indexable = n.sons[i]
  1092. template `[]=`*(n: Indexable, i: int; x: Indexable) = n.sons[i] = x
  1093. template `[]`*(n: Indexable, i: BackwardsIndex): Indexable = n[n.len - i.int]
  1094. template `[]=`*(n: Indexable, i: BackwardsIndex; x: Indexable) = n[n.len - i.int] = x
  1095. proc getDeclPragma*(n: PNode): PNode =
  1096. ## return the `nkPragma` node for declaration `n`, or `nil` if no pragma was found.
  1097. ## Currently only supports routineDefs + {nkTypeDef}.
  1098. case n.kind
  1099. of routineDefs:
  1100. if n[pragmasPos].kind != nkEmpty: result = n[pragmasPos]
  1101. else: result = nil
  1102. of nkTypeDef:
  1103. #[
  1104. type F3*{.deprecated: "x3".} = int
  1105. TypeSection
  1106. TypeDef
  1107. PragmaExpr
  1108. Postfix
  1109. Ident "*"
  1110. Ident "F3"
  1111. Pragma
  1112. ExprColonExpr
  1113. Ident "deprecated"
  1114. StrLit "x3"
  1115. Empty
  1116. Ident "int"
  1117. ]#
  1118. if n[0].kind == nkPragmaExpr:
  1119. result = n[0][1]
  1120. else:
  1121. result = nil
  1122. else:
  1123. # support as needed for `nkIdentDefs` etc.
  1124. result = nil
  1125. if result != nil:
  1126. assert result.kind == nkPragma, $(result.kind, n.kind)
  1127. proc extractPragma*(s: PSym): PNode =
  1128. ## gets the pragma node of routine/type/var/let/const symbol `s`
  1129. if s.kind in routineKinds:
  1130. result = s.ast[pragmasPos]
  1131. elif s.kind in {skType, skVar, skLet, skConst}:
  1132. if s.ast != nil and s.ast.len > 0:
  1133. if s.ast[0].kind == nkPragmaExpr and s.ast[0].len > 1:
  1134. # s.ast = nkTypedef / nkPragmaExpr / [nkSym, nkPragma]
  1135. result = s.ast[0][1]
  1136. else:
  1137. result = nil
  1138. else:
  1139. result = nil
  1140. else:
  1141. result = nil
  1142. assert result == nil or result.kind == nkPragma
  1143. proc skipPragmaExpr*(n: PNode): PNode =
  1144. ## if pragma expr, give the node the pragmas are applied to,
  1145. ## otherwise give node itself
  1146. if n.kind == nkPragmaExpr:
  1147. result = n[0]
  1148. else:
  1149. result = n
  1150. proc setInfoRecursive*(n: PNode, info: TLineInfo) =
  1151. ## set line info recursively
  1152. if n != nil:
  1153. for i in 0..<n.safeLen: setInfoRecursive(n[i], info)
  1154. n.info = info
  1155. when defined(useNodeIds):
  1156. const nodeIdToDebug* = -1 # 2322968
  1157. var gNodeId: int
  1158. template newNodeImpl(info2) =
  1159. result = PNode(kind: kind, info: info2)
  1160. when false:
  1161. # this would add overhead, so we skip it; it results in a small amount of leaked entries
  1162. # for old PNode that gets re-allocated at the same address as a PNode that
  1163. # has `nfHasComment` set (and an entry in that table). Only `nfHasComment`
  1164. # should be used to test whether a PNode has a comment; gconfig.comments
  1165. # can contain extra entries for deleted PNode's with comments.
  1166. gconfig.comments.del(cast[int](result))
  1167. template setIdMaybe() =
  1168. when defined(useNodeIds):
  1169. result.id = gNodeId
  1170. if result.id == nodeIdToDebug:
  1171. echo "KIND ", result.kind
  1172. writeStackTrace()
  1173. inc gNodeId
  1174. proc newNode*(kind: TNodeKind): PNode =
  1175. ## new node with unknown line info, no type, and no children
  1176. newNodeImpl(unknownLineInfo)
  1177. setIdMaybe()
  1178. proc newNodeI*(kind: TNodeKind, info: TLineInfo): PNode =
  1179. ## new node with line info, no type, and no children
  1180. newNodeImpl(info)
  1181. setIdMaybe()
  1182. proc newNodeI*(kind: TNodeKind, info: TLineInfo, children: int): PNode =
  1183. ## new node with line info, type, and children
  1184. newNodeImpl(info)
  1185. if children > 0:
  1186. newSeq(result.sons, children)
  1187. setIdMaybe()
  1188. proc newNodeIT*(kind: TNodeKind, info: TLineInfo, typ: PType): PNode =
  1189. ## new node with line info, type, and no children
  1190. result = newNode(kind)
  1191. result.info = info
  1192. result.typ = typ
  1193. proc newTree*(kind: TNodeKind; children: varargs[PNode]): PNode =
  1194. result = newNode(kind)
  1195. if children.len > 0:
  1196. result.info = children[0].info
  1197. result.sons = @children
  1198. proc newTreeI*(kind: TNodeKind; info: TLineInfo; children: varargs[PNode]): PNode =
  1199. result = newNodeI(kind, info)
  1200. if children.len > 0:
  1201. result.info = children[0].info
  1202. result.sons = @children
  1203. proc newTreeIT*(kind: TNodeKind; info: TLineInfo; typ: PType; children: varargs[PNode]): PNode =
  1204. result = newNodeIT(kind, info, typ)
  1205. if children.len > 0:
  1206. result.info = children[0].info
  1207. result.sons = @children
  1208. template previouslyInferred*(t: PType): PType =
  1209. if t.sons.len > 1: t.lastSon else: nil
  1210. when false:
  1211. import tables, strutils
  1212. var x: CountTable[string]
  1213. addQuitProc proc () {.noconv.} =
  1214. for k, v in pairs(x):
  1215. echo k
  1216. echo v
  1217. proc newSym*(symKind: TSymKind, name: PIdent, idgen: IdGenerator; owner: PSym,
  1218. info: TLineInfo; options: TOptions = {}): PSym =
  1219. # generates a symbol and initializes the hash field too
  1220. assert not name.isNil
  1221. let id = nextSymId idgen
  1222. result = PSym(name: name, kind: symKind, flags: {}, info: info, itemId: id,
  1223. options: options, owner: owner, offset: defaultOffset,
  1224. disamb: getOrDefault(idgen.disambTable, name).int32)
  1225. idgen.disambTable.inc name
  1226. when false:
  1227. if id.module == 48 and id.item == 39:
  1228. writeStackTrace()
  1229. echo "kind ", symKind, " ", name.s
  1230. if owner != nil: echo owner.name.s
  1231. proc astdef*(s: PSym): PNode =
  1232. # get only the definition (initializer) portion of the ast
  1233. if s.ast != nil and s.ast.kind in {nkIdentDefs, nkConstDef}:
  1234. s.ast[2]
  1235. else:
  1236. s.ast
  1237. proc isMetaType*(t: PType): bool =
  1238. return t.kind in tyMetaTypes or
  1239. (t.kind == tyStatic and t.n == nil) or
  1240. tfHasMeta in t.flags
  1241. proc isUnresolvedStatic*(t: PType): bool =
  1242. return t.kind == tyStatic and t.n == nil
  1243. proc linkTo*(t: PType, s: PSym): PType {.discardable.} =
  1244. t.sym = s
  1245. s.typ = t
  1246. result = t
  1247. proc linkTo*(s: PSym, t: PType): PSym {.discardable.} =
  1248. t.sym = s
  1249. s.typ = t
  1250. result = s
  1251. template fileIdx*(c: PSym): FileIndex =
  1252. # XXX: this should be used only on module symbols
  1253. c.position.FileIndex
  1254. template filename*(c: PSym): string =
  1255. # XXX: this should be used only on module symbols
  1256. c.position.FileIndex.toFilename
  1257. proc appendToModule*(m: PSym, n: PNode) =
  1258. ## The compiler will use this internally to add nodes that will be
  1259. ## appended to the module after the sem pass
  1260. if m.ast == nil:
  1261. m.ast = newNode(nkStmtList)
  1262. m.ast.sons = @[n]
  1263. else:
  1264. assert m.ast.kind == nkStmtList
  1265. m.ast.sons.add(n)
  1266. const # for all kind of hash tables:
  1267. GrowthFactor* = 2 # must be power of 2, > 0
  1268. StartSize* = 8 # must be power of 2, > 0
  1269. proc copyStrTable*(dest: var TStrTable, src: TStrTable) =
  1270. dest.counter = src.counter
  1271. setLen(dest.data, src.data.len)
  1272. for i in 0..high(src.data): dest.data[i] = src.data[i]
  1273. proc copyIdTable*(dest: var TIdTable, src: TIdTable) =
  1274. dest.counter = src.counter
  1275. newSeq(dest.data, src.data.len)
  1276. for i in 0..high(src.data): dest.data[i] = src.data[i]
  1277. proc copyObjectSet*(dest: var TObjectSet, src: TObjectSet) =
  1278. dest.counter = src.counter
  1279. setLen(dest.data, src.data.len)
  1280. for i in 0..high(src.data): dest.data[i] = src.data[i]
  1281. proc discardSons*(father: PNode) =
  1282. father.sons = @[]
  1283. proc withInfo*(n: PNode, info: TLineInfo): PNode =
  1284. n.info = info
  1285. return n
  1286. proc newIdentNode*(ident: PIdent, info: TLineInfo): PNode =
  1287. result = newNode(nkIdent)
  1288. result.ident = ident
  1289. result.info = info
  1290. proc newSymNode*(sym: PSym): PNode =
  1291. result = newNode(nkSym)
  1292. result.sym = sym
  1293. result.typ = sym.typ
  1294. result.info = sym.info
  1295. proc newSymNode*(sym: PSym, info: TLineInfo): PNode =
  1296. result = newNode(nkSym)
  1297. result.sym = sym
  1298. result.typ = sym.typ
  1299. result.info = info
  1300. proc newIntNode*(kind: TNodeKind, intVal: BiggestInt): PNode =
  1301. result = newNode(kind)
  1302. result.intVal = intVal
  1303. proc newIntNode*(kind: TNodeKind, intVal: Int128): PNode =
  1304. result = newNode(kind)
  1305. result.intVal = castToInt64(intVal)
  1306. proc lastSon*(n: Indexable): Indexable = n.sons[^1]
  1307. proc skipTypes*(t: PType, kinds: TTypeKinds): PType =
  1308. ## Used throughout the compiler code to test whether a type tree contains or
  1309. ## doesn't contain a specific type/types - it is often the case that only the
  1310. ## last child nodes of a type tree need to be searched. This is a really hot
  1311. ## path within the compiler!
  1312. result = t
  1313. while result.kind in kinds: result = lastSon(result)
  1314. proc newIntTypeNode*(intVal: BiggestInt, typ: PType): PNode =
  1315. let kind = skipTypes(typ, abstractVarRange).kind
  1316. case kind
  1317. of tyInt: result = newNode(nkIntLit)
  1318. of tyInt8: result = newNode(nkInt8Lit)
  1319. of tyInt16: result = newNode(nkInt16Lit)
  1320. of tyInt32: result = newNode(nkInt32Lit)
  1321. of tyInt64: result = newNode(nkInt64Lit)
  1322. of tyChar: result = newNode(nkCharLit)
  1323. of tyUInt: result = newNode(nkUIntLit)
  1324. of tyUInt8: result = newNode(nkUInt8Lit)
  1325. of tyUInt16: result = newNode(nkUInt16Lit)
  1326. of tyUInt32: result = newNode(nkUInt32Lit)
  1327. of tyUInt64: result = newNode(nkUInt64Lit)
  1328. of tyBool, tyEnum:
  1329. # XXX: does this really need to be the kind nkIntLit?
  1330. result = newNode(nkIntLit)
  1331. of tyStatic: # that's a pre-existing bug, will fix in another PR
  1332. result = newNode(nkIntLit)
  1333. else: raiseAssert $kind
  1334. result.intVal = intVal
  1335. result.typ = typ
  1336. proc newIntTypeNode*(intVal: Int128, typ: PType): PNode =
  1337. # XXX: introduce range check
  1338. newIntTypeNode(castToInt64(intVal), typ)
  1339. proc newFloatNode*(kind: TNodeKind, floatVal: BiggestFloat): PNode =
  1340. result = newNode(kind)
  1341. result.floatVal = floatVal
  1342. proc newStrNode*(kind: TNodeKind, strVal: string): PNode =
  1343. result = newNode(kind)
  1344. result.strVal = strVal
  1345. proc newStrNode*(strVal: string; info: TLineInfo): PNode =
  1346. result = newNodeI(nkStrLit, info)
  1347. result.strVal = strVal
  1348. proc newProcNode*(kind: TNodeKind, info: TLineInfo, body: PNode,
  1349. params,
  1350. name, pattern, genericParams,
  1351. pragmas, exceptions: PNode): PNode =
  1352. result = newNodeI(kind, info)
  1353. result.sons = @[name, pattern, genericParams, params,
  1354. pragmas, exceptions, body]
  1355. const
  1356. AttachedOpToStr*: array[TTypeAttachedOp, string] = [
  1357. "=wasMoved", "=destroy", "=copy", "=dup", "=sink", "=trace", "=deepcopy"]
  1358. proc `$`*(s: PSym): string =
  1359. if s != nil:
  1360. result = s.name.s & "@" & $s.id
  1361. else:
  1362. result = "<nil>"
  1363. iterator items*(t: PType): PType =
  1364. for i in 0..<t.sons.len: yield t.sons[i]
  1365. iterator pairs*(n: PType): tuple[i: int, n: PType] =
  1366. for i in 0..<n.sons.len: yield (i, n.sons[i])
  1367. proc newType*(kind: TTypeKind, id: ItemId; owner: PSym, sons: seq[PType] = @[]): PType =
  1368. result = PType(kind: kind, owner: owner, size: defaultSize,
  1369. align: defaultAlignment, itemId: id,
  1370. uniqueId: id, sons: sons)
  1371. when false:
  1372. if result.itemId.module == 55 and result.itemId.item == 2:
  1373. echo "KNID ", kind
  1374. writeStackTrace()
  1375. template newType*(kind: TTypeKind, id: ItemId; owner: PSym, parent: PType): PType =
  1376. newType(kind, id, owner, parent.sons)
  1377. proc newType*(prev: PType, sons: seq[PType]): PType =
  1378. result = prev
  1379. result.sons = sons
  1380. proc addSon*(father, son: PType) =
  1381. # todo fixme: in IC, `son` might be nil
  1382. father.sons.add(son)
  1383. proc mergeLoc(a: var TLoc, b: TLoc) =
  1384. if a.k == low(typeof(a.k)): a.k = b.k
  1385. if a.storage == low(typeof(a.storage)): a.storage = b.storage
  1386. a.flags.incl b.flags
  1387. if a.lode == nil: a.lode = b.lode
  1388. if a.r == "": a.r = b.r
  1389. proc newSons*(father: Indexable, length: int) =
  1390. setLen(father.sons, length)
  1391. proc assignType*(dest, src: PType) =
  1392. dest.kind = src.kind
  1393. dest.flags = src.flags
  1394. dest.callConv = src.callConv
  1395. dest.n = src.n
  1396. dest.size = src.size
  1397. dest.align = src.align
  1398. # this fixes 'type TLock = TSysLock':
  1399. if src.sym != nil:
  1400. if dest.sym != nil:
  1401. dest.sym.flags.incl src.sym.flags-{sfUsed, sfExported}
  1402. if dest.sym.annex == nil: dest.sym.annex = src.sym.annex
  1403. mergeLoc(dest.sym.loc, src.sym.loc)
  1404. else:
  1405. dest.sym = src.sym
  1406. newSons(dest, src.len)
  1407. for i in 0..<src.len: dest[i] = src[i]
  1408. proc copyType*(t: PType, id: ItemId, owner: PSym): PType =
  1409. result = newType(t.kind, id, owner)
  1410. assignType(result, t)
  1411. result.sym = t.sym # backend-info should not be copied
  1412. proc exactReplica*(t: PType): PType =
  1413. result = copyType(t, t.itemId, t.owner)
  1414. proc copySym*(s: PSym; idgen: IdGenerator): PSym =
  1415. result = newSym(s.kind, s.name, idgen, s.owner, s.info, s.options)
  1416. #result.ast = nil # BUGFIX; was: s.ast which made problems
  1417. result.typ = s.typ
  1418. result.flags = s.flags
  1419. result.magic = s.magic
  1420. result.options = s.options
  1421. result.position = s.position
  1422. result.loc = s.loc
  1423. result.annex = s.annex # BUGFIX
  1424. result.constraint = s.constraint
  1425. if result.kind in {skVar, skLet, skField}:
  1426. result.guard = s.guard
  1427. result.bitsize = s.bitsize
  1428. result.alignment = s.alignment
  1429. proc createModuleAlias*(s: PSym, idgen: IdGenerator, newIdent: PIdent, info: TLineInfo;
  1430. options: TOptions): PSym =
  1431. result = newSym(s.kind, newIdent, idgen, s.owner, info, options)
  1432. # keep ID!
  1433. result.ast = s.ast
  1434. #result.id = s.id # XXX figure out what to do with the ID.
  1435. result.flags = s.flags
  1436. result.options = s.options
  1437. result.position = s.position
  1438. result.loc = s.loc
  1439. result.annex = s.annex
  1440. proc initStrTable*(): TStrTable =
  1441. result = TStrTable(counter: 0)
  1442. newSeq(result.data, StartSize)
  1443. proc initIdTable*(): TIdTable =
  1444. result = TIdTable(counter: 0)
  1445. newSeq(result.data, StartSize)
  1446. proc resetIdTable*(x: var TIdTable) =
  1447. x.counter = 0
  1448. # clear and set to old initial size:
  1449. setLen(x.data, 0)
  1450. setLen(x.data, StartSize)
  1451. proc initObjectSet*(): TObjectSet =
  1452. result = TObjectSet(counter: 0)
  1453. newSeq(result.data, StartSize)
  1454. proc initIdNodeTable*(): TIdNodeTable =
  1455. result = TIdNodeTable(counter: 0)
  1456. newSeq(result.data, StartSize)
  1457. proc initNodeTable*(): TNodeTable =
  1458. result = TNodeTable(counter: 0)
  1459. newSeq(result.data, StartSize)
  1460. proc skipTypes*(t: PType, kinds: TTypeKinds; maxIters: int): PType =
  1461. result = t
  1462. var i = maxIters
  1463. while result.kind in kinds:
  1464. result = lastSon(result)
  1465. dec i
  1466. if i == 0: return nil
  1467. proc skipTypesOrNil*(t: PType, kinds: TTypeKinds): PType =
  1468. ## same as skipTypes but handles 'nil'
  1469. result = t
  1470. while result != nil and result.kind in kinds:
  1471. if result.len == 0: return nil
  1472. result = lastSon(result)
  1473. proc isGCedMem*(t: PType): bool {.inline.} =
  1474. result = t.kind in {tyString, tyRef, tySequence} or
  1475. t.kind == tyProc and t.callConv == ccClosure
  1476. proc propagateToOwner*(owner, elem: PType; propagateHasAsgn = true) =
  1477. owner.flags.incl elem.flags * {tfHasMeta, tfTriggersCompileTime}
  1478. if tfNotNil in elem.flags:
  1479. if owner.kind in {tyGenericInst, tyGenericBody, tyGenericInvocation}:
  1480. owner.flags.incl tfNotNil
  1481. if elem.isMetaType:
  1482. owner.flags.incl tfHasMeta
  1483. let mask = elem.flags * {tfHasAsgn, tfHasOwned}
  1484. if mask != {} and propagateHasAsgn:
  1485. let o2 = owner.skipTypes({tyGenericInst, tyAlias, tySink})
  1486. if o2.kind in {tyTuple, tyObject, tyArray,
  1487. tySequence, tySet, tyDistinct}:
  1488. o2.flags.incl mask
  1489. owner.flags.incl mask
  1490. if owner.kind notin {tyProc, tyGenericInst, tyGenericBody,
  1491. tyGenericInvocation, tyPtr}:
  1492. let elemB = elem.skipTypes({tyGenericInst, tyAlias, tySink})
  1493. if elemB.isGCedMem or tfHasGCedMem in elemB.flags:
  1494. # for simplicity, we propagate this flag even to generics. We then
  1495. # ensure this doesn't bite us in sempass2.
  1496. owner.flags.incl tfHasGCedMem
  1497. proc rawAddSon*(father, son: PType; propagateHasAsgn = true) =
  1498. father.sons.add(son)
  1499. if not son.isNil: propagateToOwner(father, son, propagateHasAsgn)
  1500. proc rawAddSonNoPropagationOfTypeFlags*(father, son: PType) =
  1501. father.sons.add(son)
  1502. proc addSonNilAllowed*(father, son: PNode) =
  1503. father.sons.add(son)
  1504. proc delSon*(father: PNode, idx: int) =
  1505. if father.len == 0: return
  1506. for i in idx..<father.len - 1: father[i] = father[i + 1]
  1507. father.sons.setLen(father.len - 1)
  1508. proc copyNode*(src: PNode): PNode =
  1509. # does not copy its sons!
  1510. if src == nil:
  1511. return nil
  1512. result = newNode(src.kind)
  1513. result.info = src.info
  1514. result.typ = src.typ
  1515. result.flags = src.flags * PersistentNodeFlags
  1516. result.comment = src.comment
  1517. when defined(useNodeIds):
  1518. if result.id == nodeIdToDebug:
  1519. echo "COMES FROM ", src.id
  1520. case src.kind
  1521. of nkCharLit..nkUInt64Lit: result.intVal = src.intVal
  1522. of nkFloatLiterals: result.floatVal = src.floatVal
  1523. of nkSym: result.sym = src.sym
  1524. of nkIdent: result.ident = src.ident
  1525. of nkStrLit..nkTripleStrLit: result.strVal = src.strVal
  1526. else: discard
  1527. when defined(nimsuggest):
  1528. result.endInfo = src.endInfo
  1529. template transitionNodeKindCommon(k: TNodeKind) =
  1530. let obj {.inject.} = n[]
  1531. n[] = TNode(kind: k, typ: obj.typ, info: obj.info, flags: obj.flags)
  1532. # n.comment = obj.comment # shouldn't be needed, the address doesnt' change
  1533. when defined(useNodeIds):
  1534. n.id = obj.id
  1535. proc transitionSonsKind*(n: PNode, kind: range[nkComesFrom..nkTupleConstr]) =
  1536. transitionNodeKindCommon(kind)
  1537. n.sons = obj.sons
  1538. proc transitionIntKind*(n: PNode, kind: range[nkCharLit..nkUInt64Lit]) =
  1539. transitionNodeKindCommon(kind)
  1540. n.intVal = obj.intVal
  1541. proc transitionIntToFloatKind*(n: PNode, kind: range[nkFloatLit..nkFloat128Lit]) =
  1542. transitionNodeKindCommon(kind)
  1543. n.floatVal = BiggestFloat(obj.intVal)
  1544. proc transitionNoneToSym*(n: PNode) =
  1545. transitionNodeKindCommon(nkSym)
  1546. template transitionSymKindCommon*(k: TSymKind) =
  1547. let obj {.inject.} = s[]
  1548. s[] = TSym(kind: k, itemId: obj.itemId, magic: obj.magic, typ: obj.typ, name: obj.name,
  1549. info: obj.info, owner: obj.owner, flags: obj.flags, ast: obj.ast,
  1550. options: obj.options, position: obj.position, offset: obj.offset,
  1551. loc: obj.loc, annex: obj.annex, constraint: obj.constraint)
  1552. when hasFFI:
  1553. s.cname = obj.cname
  1554. when defined(nimsuggest):
  1555. s.allUsages = obj.allUsages
  1556. proc transitionGenericParamToType*(s: PSym) =
  1557. transitionSymKindCommon(skType)
  1558. proc transitionRoutineSymKind*(s: PSym, kind: range[skProc..skTemplate]) =
  1559. transitionSymKindCommon(kind)
  1560. s.gcUnsafetyReason = obj.gcUnsafetyReason
  1561. s.transformedBody = obj.transformedBody
  1562. proc transitionToLet*(s: PSym) =
  1563. transitionSymKindCommon(skLet)
  1564. s.guard = obj.guard
  1565. s.bitsize = obj.bitsize
  1566. s.alignment = obj.alignment
  1567. template copyNodeImpl(dst, src, processSonsStmt) =
  1568. if src == nil: return
  1569. dst = newNode(src.kind)
  1570. dst.info = src.info
  1571. when defined(nimsuggest):
  1572. result.endInfo = src.endInfo
  1573. dst.typ = src.typ
  1574. dst.flags = src.flags * PersistentNodeFlags
  1575. dst.comment = src.comment
  1576. when defined(useNodeIds):
  1577. if dst.id == nodeIdToDebug:
  1578. echo "COMES FROM ", src.id
  1579. case src.kind
  1580. of nkCharLit..nkUInt64Lit: dst.intVal = src.intVal
  1581. of nkFloatLiterals: dst.floatVal = src.floatVal
  1582. of nkSym: dst.sym = src.sym
  1583. of nkIdent: dst.ident = src.ident
  1584. of nkStrLit..nkTripleStrLit: dst.strVal = src.strVal
  1585. else: processSonsStmt
  1586. proc shallowCopy*(src: PNode): PNode =
  1587. # does not copy its sons, but provides space for them:
  1588. copyNodeImpl(result, src):
  1589. newSeq(result.sons, src.len)
  1590. proc copyTree*(src: PNode): PNode =
  1591. # copy a whole syntax tree; performs deep copying
  1592. copyNodeImpl(result, src):
  1593. newSeq(result.sons, src.len)
  1594. for i in 0..<src.len:
  1595. result[i] = copyTree(src[i])
  1596. proc copyTreeWithoutNode*(src, skippedNode: PNode): PNode =
  1597. copyNodeImpl(result, src):
  1598. result.sons = newSeqOfCap[PNode](src.len)
  1599. for n in src.sons:
  1600. if n != skippedNode:
  1601. result.sons.add copyTreeWithoutNode(n, skippedNode)
  1602. proc hasSonWith*(n: PNode, kind: TNodeKind): bool =
  1603. for i in 0..<n.len:
  1604. if n[i].kind == kind:
  1605. return true
  1606. result = false
  1607. proc hasNilSon*(n: PNode): bool =
  1608. for i in 0..<n.safeLen:
  1609. if n[i] == nil:
  1610. return true
  1611. elif hasNilSon(n[i]):
  1612. return true
  1613. result = false
  1614. proc containsNode*(n: PNode, kinds: TNodeKinds): bool =
  1615. result = false
  1616. if n == nil: return
  1617. case n.kind
  1618. of nkEmpty..nkNilLit: result = n.kind in kinds
  1619. else:
  1620. for i in 0..<n.len:
  1621. if n.kind in kinds or containsNode(n[i], kinds): return true
  1622. proc hasSubnodeWith*(n: PNode, kind: TNodeKind): bool =
  1623. case n.kind
  1624. of nkEmpty..nkNilLit, nkFormalParams: result = n.kind == kind
  1625. else:
  1626. for i in 0..<n.len:
  1627. if (n[i].kind == kind) or hasSubnodeWith(n[i], kind):
  1628. return true
  1629. result = false
  1630. proc getInt*(a: PNode): Int128 =
  1631. case a.kind
  1632. of nkCharLit, nkUIntLit..nkUInt64Lit:
  1633. result = toInt128(cast[uint64](a.intVal))
  1634. of nkInt8Lit..nkInt64Lit:
  1635. result = toInt128(a.intVal)
  1636. of nkIntLit:
  1637. # XXX: enable this assert
  1638. # assert a.typ.kind notin {tyChar, tyUint..tyUInt64}
  1639. result = toInt128(a.intVal)
  1640. else:
  1641. raiseRecoverableError("cannot extract number from invalid AST node")
  1642. proc getInt64*(a: PNode): int64 {.deprecated: "use getInt".} =
  1643. case a.kind
  1644. of nkCharLit, nkUIntLit..nkUInt64Lit, nkIntLit..nkInt64Lit:
  1645. result = a.intVal
  1646. else:
  1647. raiseRecoverableError("cannot extract number from invalid AST node")
  1648. proc getFloat*(a: PNode): BiggestFloat =
  1649. case a.kind
  1650. of nkFloatLiterals: result = a.floatVal
  1651. of nkCharLit, nkUIntLit..nkUInt64Lit, nkIntLit..nkInt64Lit:
  1652. result = BiggestFloat a.intVal
  1653. else:
  1654. raiseRecoverableError("cannot extract number from invalid AST node")
  1655. #doAssert false, "getFloat"
  1656. #internalError(a.info, "getFloat")
  1657. #result = 0.0
  1658. proc getStr*(a: PNode): string =
  1659. case a.kind
  1660. of nkStrLit..nkTripleStrLit: result = a.strVal
  1661. of nkNilLit:
  1662. # let's hope this fixes more problems than it creates:
  1663. result = ""
  1664. else:
  1665. raiseRecoverableError("cannot extract string from invalid AST node")
  1666. #doAssert false, "getStr"
  1667. #internalError(a.info, "getStr")
  1668. #result = ""
  1669. proc getStrOrChar*(a: PNode): string =
  1670. case a.kind
  1671. of nkStrLit..nkTripleStrLit: result = a.strVal
  1672. of nkCharLit..nkUInt64Lit: result = $chr(int(a.intVal))
  1673. else:
  1674. raiseRecoverableError("cannot extract string from invalid AST node")
  1675. #doAssert false, "getStrOrChar"
  1676. #internalError(a.info, "getStrOrChar")
  1677. #result = ""
  1678. proc isGenericParams*(n: PNode): bool {.inline.} =
  1679. ## used to judge whether a node is generic params.
  1680. n != nil and n.kind == nkGenericParams
  1681. proc isGenericRoutine*(n: PNode): bool {.inline.} =
  1682. n != nil and n.kind in callableDefs and n[genericParamsPos].isGenericParams
  1683. proc isGenericRoutineStrict*(s: PSym): bool {.inline.} =
  1684. ## determines if this symbol represents a generic routine
  1685. ## the unusual name is so it doesn't collide and eventually replaces
  1686. ## `isGenericRoutine`
  1687. s.kind in skProcKinds and s.ast.isGenericRoutine
  1688. proc isGenericRoutine*(s: PSym): bool {.inline.} =
  1689. ## determines if this symbol represents a generic routine or an instance of
  1690. ## one. This should be renamed accordingly and `isGenericRoutineStrict`
  1691. ## should take this name instead.
  1692. ##
  1693. ## Warning/XXX: Unfortunately, it considers a proc kind symbol flagged with
  1694. ## sfFromGeneric as a generic routine. Instead this should likely not be the
  1695. ## case and the concepts should be teased apart:
  1696. ## - generic definition
  1697. ## - generic instance
  1698. ## - either generic definition or instance
  1699. s.kind in skProcKinds and (sfFromGeneric in s.flags or
  1700. s.ast.isGenericRoutine)
  1701. proc skipGenericOwner*(s: PSym): PSym =
  1702. ## Generic instantiations are owned by their originating generic
  1703. ## symbol. This proc skips such owners and goes straight to the owner
  1704. ## of the generic itself (the module or the enclosing proc).
  1705. result = if s.kind in skProcKinds and sfFromGeneric in s.flags and s.owner.kind != skModule:
  1706. s.owner.owner
  1707. else:
  1708. s.owner
  1709. proc originatingModule*(s: PSym): PSym =
  1710. result = s.owner
  1711. while result.kind != skModule: result = result.owner
  1712. proc isRoutine*(s: PSym): bool {.inline.} =
  1713. result = s.kind in skProcKinds
  1714. proc isCompileTimeProc*(s: PSym): bool {.inline.} =
  1715. result = s.kind == skMacro or
  1716. s.kind in {skProc, skFunc} and sfCompileTime in s.flags
  1717. proc hasPattern*(s: PSym): bool {.inline.} =
  1718. result = isRoutine(s) and s.ast[patternPos].kind != nkEmpty
  1719. iterator items*(n: PNode): PNode =
  1720. for i in 0..<n.safeLen: yield n[i]
  1721. iterator pairs*(n: PNode): tuple[i: int, n: PNode] =
  1722. for i in 0..<n.safeLen: yield (i, n[i])
  1723. proc isAtom*(n: PNode): bool {.inline.} =
  1724. result = n.kind >= nkNone and n.kind <= nkNilLit
  1725. proc isEmptyType*(t: PType): bool {.inline.} =
  1726. ## 'void' and 'typed' types are often equivalent to 'nil' these days:
  1727. result = t == nil or t.kind in {tyVoid, tyTyped}
  1728. proc makeStmtList*(n: PNode): PNode =
  1729. if n.kind == nkStmtList:
  1730. result = n
  1731. else:
  1732. result = newNodeI(nkStmtList, n.info)
  1733. result.add n
  1734. proc skipStmtList*(n: PNode): PNode =
  1735. if n.kind in {nkStmtList, nkStmtListExpr}:
  1736. for i in 0..<n.len-1:
  1737. if n[i].kind notin {nkEmpty, nkCommentStmt}: return n
  1738. result = n.lastSon
  1739. else:
  1740. result = n
  1741. proc toVar*(typ: PType; kind: TTypeKind; idgen: IdGenerator): PType =
  1742. ## If ``typ`` is not a tyVar then it is converted into a `var <typ>` and
  1743. ## returned. Otherwise ``typ`` is simply returned as-is.
  1744. result = typ
  1745. if typ.kind != kind:
  1746. result = newType(kind, nextTypeId(idgen), typ.owner)
  1747. rawAddSon(result, typ)
  1748. proc toRef*(typ: PType; idgen: IdGenerator): PType =
  1749. ## If ``typ`` is a tyObject then it is converted into a `ref <typ>` and
  1750. ## returned. Otherwise ``typ`` is simply returned as-is.
  1751. result = typ
  1752. if typ.skipTypes({tyAlias, tyGenericInst}).kind == tyObject:
  1753. result = newType(tyRef, nextTypeId(idgen), typ.owner)
  1754. rawAddSon(result, typ)
  1755. proc toObject*(typ: PType): PType =
  1756. ## If ``typ`` is a tyRef then its immediate son is returned (which in many
  1757. ## cases should be a ``tyObject``).
  1758. ## Otherwise ``typ`` is simply returned as-is.
  1759. let t = typ.skipTypes({tyAlias, tyGenericInst})
  1760. if t.kind == tyRef: t.lastSon
  1761. else: typ
  1762. proc toObjectFromRefPtrGeneric*(typ: PType): PType =
  1763. #[
  1764. See also `toObject`.
  1765. Finds the underlying `object`, even in cases like these:
  1766. type
  1767. B[T] = object f0: int
  1768. A1[T] = ref B[T]
  1769. A2[T] = ref object f1: int
  1770. A3 = ref object f2: int
  1771. A4 = object f3: int
  1772. ]#
  1773. result = typ
  1774. while true:
  1775. case result.kind
  1776. of tyGenericBody: result = result.lastSon
  1777. of tyRef, tyPtr, tyGenericInst, tyGenericInvocation, tyAlias: result = result[0]
  1778. # automatic dereferencing is deep, refs #18298.
  1779. else: break
  1780. # result does not have to be object type
  1781. proc isImportedException*(t: PType; conf: ConfigRef): bool =
  1782. assert t != nil
  1783. if conf.exc != excCpp:
  1784. return false
  1785. let base = t.skipTypes({tyAlias, tyPtr, tyDistinct, tyGenericInst})
  1786. if base.sym != nil and {sfCompileToCpp, sfImportc} * base.sym.flags != {}:
  1787. result = true
  1788. else:
  1789. result = false
  1790. proc isInfixAs*(n: PNode): bool =
  1791. return n.kind == nkInfix and n[0].kind == nkIdent and n[0].ident.s == "as"
  1792. proc skipColon*(n: PNode): PNode =
  1793. result = n
  1794. if n.kind == nkExprColonExpr:
  1795. result = n[1]
  1796. proc findUnresolvedStatic*(n: PNode): PNode =
  1797. if n.kind == nkSym and n.typ != nil and n.typ.kind == tyStatic and n.typ.n == nil:
  1798. return n
  1799. if n.typ != nil and n.typ.kind == tyTypeDesc:
  1800. let t = skipTypes(n.typ, {tyTypeDesc})
  1801. if t.kind == tyGenericParam and t.len == 0:
  1802. return n
  1803. for son in n:
  1804. let n = son.findUnresolvedStatic
  1805. if n != nil: return n
  1806. return nil
  1807. when false:
  1808. proc containsNil*(n: PNode): bool =
  1809. # only for debugging
  1810. if n.isNil: return true
  1811. for i in 0..<n.safeLen:
  1812. if n[i].containsNil: return true
  1813. template hasDestructor*(t: PType): bool = {tfHasAsgn, tfHasOwned} * t.flags != {}
  1814. template incompleteType*(t: PType): bool =
  1815. t.sym != nil and {sfForward, sfNoForward} * t.sym.flags == {sfForward}
  1816. template typeCompleted*(s: PSym) =
  1817. incl s.flags, sfNoForward
  1818. template detailedInfo*(sym: PSym): string =
  1819. sym.name.s
  1820. proc isInlineIterator*(typ: PType): bool {.inline.} =
  1821. typ.kind == tyProc and tfIterator in typ.flags and typ.callConv != ccClosure
  1822. proc isIterator*(typ: PType): bool {.inline.} =
  1823. typ.kind == tyProc and tfIterator in typ.flags
  1824. proc isClosureIterator*(typ: PType): bool {.inline.} =
  1825. typ.kind == tyProc and tfIterator in typ.flags and typ.callConv == ccClosure
  1826. proc isClosure*(typ: PType): bool {.inline.} =
  1827. typ.kind == tyProc and typ.callConv == ccClosure
  1828. proc isNimcall*(s: PSym): bool {.inline.} =
  1829. s.typ.callConv == ccNimCall
  1830. proc isExplicitCallConv*(s: PSym): bool {.inline.} =
  1831. tfExplicitCallConv in s.typ.flags
  1832. proc isSinkParam*(s: PSym): bool {.inline.} =
  1833. s.kind == skParam and (s.typ.kind == tySink or tfHasOwned in s.typ.flags)
  1834. proc isSinkType*(t: PType): bool {.inline.} =
  1835. t.kind == tySink or tfHasOwned in t.flags
  1836. proc newProcType*(info: TLineInfo; id: ItemId; owner: PSym): PType =
  1837. result = newType(tyProc, id, owner)
  1838. result.n = newNodeI(nkFormalParams, info)
  1839. rawAddSon(result, nil) # return type
  1840. # result.n[0] used to be `nkType`, but now it's `nkEffectList` because
  1841. # the effects are now stored in there too ... this is a bit hacky, but as
  1842. # usual we desperately try to save memory:
  1843. result.n.add newNodeI(nkEffectList, info)
  1844. proc addParam*(procType: PType; param: PSym) =
  1845. param.position = procType.len-1
  1846. procType.n.add newSymNode(param)
  1847. rawAddSon(procType, param.typ)
  1848. const magicsThatCanRaise = {
  1849. mNone, mSlurp, mStaticExec, mParseExprToAst, mParseStmtToAst, mEcho}
  1850. proc canRaiseConservative*(fn: PNode): bool =
  1851. if fn.kind == nkSym and fn.sym.magic notin magicsThatCanRaise:
  1852. result = false
  1853. else:
  1854. result = true
  1855. proc canRaise*(fn: PNode): bool =
  1856. if fn.kind == nkSym and (fn.sym.magic notin magicsThatCanRaise or
  1857. {sfImportc, sfInfixCall} * fn.sym.flags == {sfImportc} or
  1858. sfGeneratedOp in fn.sym.flags):
  1859. result = false
  1860. elif fn.kind == nkSym and fn.sym.magic == mEcho:
  1861. result = true
  1862. else:
  1863. # TODO check for n having sons? or just return false for now if not
  1864. if fn.typ != nil and fn.typ.n != nil and fn.typ.n[0].kind == nkSym:
  1865. result = false
  1866. else:
  1867. result = fn.typ != nil and fn.typ.n != nil and ((fn.typ.n[0].len < effectListLen) or
  1868. (fn.typ.n[0][exceptionEffects] != nil and
  1869. fn.typ.n[0][exceptionEffects].safeLen > 0))
  1870. proc toHumanStrImpl[T](kind: T, num: static int): string =
  1871. result = $kind
  1872. result = result[num..^1]
  1873. result[0] = result[0].toLowerAscii
  1874. proc toHumanStr*(kind: TSymKind): string =
  1875. ## strips leading `sk`
  1876. result = toHumanStrImpl(kind, 2)
  1877. proc toHumanStr*(kind: TTypeKind): string =
  1878. ## strips leading `tk`
  1879. result = toHumanStrImpl(kind, 2)
  1880. proc skipAddr*(n: PNode): PNode {.inline.} =
  1881. (if n.kind == nkHiddenAddr: n[0] else: n)
  1882. proc isNewStyleConcept*(n: PNode): bool {.inline.} =
  1883. assert n.kind == nkTypeClassTy
  1884. result = n[0].kind == nkEmpty
  1885. proc isOutParam*(t: PType): bool {.inline.} = tfIsOutParam in t.flags
  1886. const
  1887. nodesToIgnoreSet* = {nkNone..pred(nkSym), succ(nkSym)..nkNilLit,
  1888. nkTypeSection, nkProcDef, nkConverterDef,
  1889. nkMethodDef, nkIteratorDef, nkMacroDef, nkTemplateDef, nkLambda, nkDo,
  1890. nkFuncDef, nkConstSection, nkConstDef, nkIncludeStmt, nkImportStmt,
  1891. nkExportStmt, nkPragma, nkCommentStmt, nkBreakState,
  1892. nkTypeOfExpr, nkMixinStmt, nkBindStmt}
  1893. proc isTrue*(n: PNode): bool =
  1894. n.kind == nkSym and n.sym.kind == skEnumField and n.sym.position != 0 or
  1895. n.kind == nkIntLit and n.intVal != 0