ast.nim 80 KB

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