ast.nim 80 KB

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