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. nkSharedTy, # 'shared T'
  200. # we use 'nkPostFix' for the 'not nil' addition
  201. nkEnumTy, # enum body
  202. nkEnumFieldDef, # `ident = expr` in an enumeration
  203. nkArgList, # argument list
  204. nkPattern, # a special pattern; used for matching
  205. nkHiddenTryStmt, # a hidden try statement
  206. nkClosure, # (prc, env)-pair (internally used for code gen)
  207. nkGotoState, # used for the state machine (for iterators)
  208. nkState, # give a label to a code section (for iterators)
  209. nkBreakState, # special break statement for easier code generation
  210. nkFuncDef, # a func
  211. nkTupleConstr # a tuple constructor
  212. nkError # erroneous AST node
  213. nkModuleRef # for .rod file support: A (moduleId, itemId) pair
  214. nkReplayAction # for .rod file support: A replay action
  215. nkNilRodNode # for .rod file support: a 'nil' PNode
  216. TNodeKinds* = set[TNodeKind]
  217. type
  218. TSymFlag* = enum # 49 flags!
  219. sfUsed, # read access of sym (for warnings) or simply used
  220. sfExported, # symbol is exported from module
  221. sfFromGeneric, # symbol is instantiation of a generic; this is needed
  222. # for symbol file generation; such symbols should always
  223. # be written into the ROD file
  224. sfGlobal, # symbol is at global scope
  225. sfForward, # symbol is forward declared
  226. sfWasForwarded, # symbol had a forward declaration
  227. # (implies it's too dangerous to patch its type signature)
  228. sfImportc, # symbol is external; imported
  229. sfExportc, # symbol is exported (under a specified name)
  230. sfMangleCpp, # mangle as cpp (combines with `sfExportc`)
  231. sfVolatile, # variable is volatile
  232. sfRegister, # variable should be placed in a register
  233. sfPure, # object is "pure" that means it has no type-information
  234. # enum is "pure", its values need qualified access
  235. # variable is "pure"; it's an explicit "global"
  236. sfNoSideEffect, # proc has no side effects
  237. sfSideEffect, # proc may have side effects; cannot prove it has none
  238. sfMainModule, # module is the main module
  239. sfSystemModule, # module is the system module
  240. sfNoReturn, # proc never returns (an exit proc)
  241. sfAddrTaken, # the variable's address is taken (ex- or implicitly);
  242. # *OR*: a proc is indirectly called (used as first class)
  243. sfCompilerProc, # proc is a compiler proc, that is a C proc that is
  244. # needed for the code generator
  245. sfEscapes # param escapes
  246. # currently unimplemented
  247. sfDiscriminant, # field is a discriminant in a record/object
  248. sfRequiresInit, # field must be initialized during construction
  249. sfDeprecated, # symbol is deprecated
  250. sfExplain, # provide more diagnostics when this symbol is used
  251. sfError, # usage of symbol should trigger a compile-time error
  252. sfShadowed, # a symbol that was shadowed in some inner scope
  253. sfThread, # proc will run as a thread
  254. # variable is a thread variable
  255. sfCppNonPod, # tells compiler to treat such types as non-pod's, so that
  256. # `thread_local` is used instead of `__thread` for
  257. # {.threadvar.} + `--threads`. Only makes sense for importcpp types.
  258. # This has a performance impact so isn't set by default.
  259. sfCompileTime, # proc can be evaluated at compile time
  260. sfConstructor, # proc is a C++ constructor
  261. sfDispatcher, # copied method symbol is the dispatcher
  262. # deprecated and unused, except for the con
  263. sfBorrow, # proc is borrowed
  264. sfInfixCall, # symbol needs infix call syntax in target language;
  265. # for interfacing with C++, JS
  266. sfNamedParamCall, # symbol needs named parameter call syntax in target
  267. # language; for interfacing with Objective C
  268. sfDiscardable, # returned value may be discarded implicitly
  269. sfOverriden, # proc is overridden
  270. sfCallsite # A flag for template symbols to tell the
  271. # compiler it should use line information from
  272. # the calling side of the macro, not from the
  273. # implementation.
  274. sfGenSym # symbol is 'gensym'ed; do not add to symbol table
  275. sfNonReloadable # symbol will be left as-is when hot code reloading is on -
  276. # meaning that it won't be renamed and/or changed in any way
  277. sfGeneratedOp # proc is a generated '='; do not inject destructors in it
  278. # variable is generated closure environment; requires early
  279. # destruction for --newruntime.
  280. sfTemplateParam # symbol is a template parameter
  281. sfCursor # variable/field is a cursor, see RFC 177 for details
  282. sfInjectDestructors # whether the proc needs the 'injectdestructors' transformation
  283. sfNeverRaises # proc can never raise an exception, not even OverflowDefect
  284. # or out-of-memory
  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. nfUseDefaultField # node has a default value (object constructor)
  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, mNSetType, 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, 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. TStrTable* = object # a table[PIdent] of PSym
  734. counter*: int
  735. data*: seq[PSym]
  736. # -------------- backend information -------------------------------
  737. TLocKind* = enum
  738. locNone, # no location
  739. locTemp, # temporary location
  740. locLocalVar, # location is a local variable
  741. locGlobalVar, # location is a global variable
  742. locParam, # location is a parameter
  743. locField, # location is a record field
  744. locExpr, # "location" is really an expression
  745. locProc, # location is a proc (an address of a procedure)
  746. locData, # location is a constant
  747. locCall, # location is a call expression
  748. locOther # location is something other
  749. TLocFlag* = enum
  750. lfIndirect, # backend introduced a pointer
  751. lfFullExternalName, # only used when 'conf.cmd == cmdNimfix': Indicates
  752. # that the symbol has been imported via 'importc: "fullname"' and
  753. # no format string.
  754. lfNoDeepCopy, # no need for a deep copy
  755. lfNoDecl, # do not declare it in C
  756. lfDynamicLib, # link symbol to dynamic library
  757. lfExportLib, # export symbol for dynamic library generation
  758. lfHeader, # include header file for symbol
  759. lfImportCompilerProc, # ``importc`` of a compilerproc
  760. lfSingleUse # no location yet and will only be used once
  761. lfEnforceDeref # a copyMem is required to dereference if this a
  762. # ptr array due to C array limitations.
  763. # See #1181, #6422, #11171
  764. lfPrepareForMutation # string location is about to be mutated (V2)
  765. TStorageLoc* = enum
  766. OnUnknown, # location is unknown (stack, heap or static)
  767. OnStatic, # in a static section
  768. OnStack, # location is on hardware stack
  769. OnHeap # location is on heap or global
  770. # (reference counting needed)
  771. TLocFlags* = set[TLocFlag]
  772. TLoc* = object
  773. k*: TLocKind # kind of location
  774. storage*: TStorageLoc
  775. flags*: TLocFlags # location's flags
  776. lode*: PNode # Node where the location came from; can be faked
  777. r*: Rope # rope value of location (code generators)
  778. # ---------------- end of backend information ------------------------------
  779. TLibKind* = enum
  780. libHeader, libDynamic
  781. TLib* = object # also misused for headers!
  782. # keep in sync with PackedLib
  783. kind*: TLibKind
  784. generated*: bool # needed for the backends:
  785. isOverriden*: bool
  786. name*: Rope
  787. path*: PNode # can be a string literal!
  788. CompilesId* = int ## id that is used for the caching logic within
  789. ## ``system.compiles``. See the seminst module.
  790. TInstantiation* = object
  791. sym*: PSym
  792. concreteTypes*: seq[PType]
  793. compilesId*: CompilesId
  794. PInstantiation* = ref TInstantiation
  795. TScope* {.acyclic.} = object
  796. depthLevel*: int
  797. symbols*: TStrTable
  798. parent*: PScope
  799. allowPrivateAccess*: seq[PSym] # # enable access to private fields
  800. PScope* = ref TScope
  801. PLib* = ref TLib
  802. TSym* {.acyclic.} = object of TIdObj # Keep in sync with PackedSym
  803. # proc and type instantiations are cached in the generic symbol
  804. case kind*: TSymKind
  805. of routineKinds:
  806. #procInstCache*: seq[PInstantiation]
  807. gcUnsafetyReason*: PSym # for better error messages regarding gcsafe
  808. transformedBody*: PNode # cached body after transf pass
  809. of skLet, skVar, skField, skForVar:
  810. guard*: PSym
  811. bitsize*: int
  812. alignment*: int # for alignment
  813. else: nil
  814. magic*: TMagic
  815. typ*: PType
  816. name*: PIdent
  817. info*: TLineInfo
  818. owner*: PSym
  819. flags*: TSymFlags
  820. ast*: PNode # syntax tree of proc, iterator, etc.:
  821. # the whole proc including header; this is used
  822. # for easy generation of proper error messages
  823. # for variant record fields the discriminant
  824. # expression
  825. # for modules, it's a placeholder for compiler
  826. # generated code that will be appended to the
  827. # module after the sem pass (see appendToModule)
  828. options*: TOptions
  829. position*: int # used for many different things:
  830. # for enum fields its position;
  831. # for fields its offset
  832. # for parameters its position (starting with 0)
  833. # for a conditional:
  834. # 1 iff the symbol is defined, else 0
  835. # (or not in symbol table)
  836. # for modules, an unique index corresponding
  837. # to the module's fileIdx
  838. # for variables a slot index for the evaluator
  839. offset*: int # offset of record field
  840. loc*: TLoc
  841. annex*: PLib # additional fields (seldom used, so we use a
  842. # reference to another object to save space)
  843. when hasFFI:
  844. cname*: string # resolved C declaration name in importc decl, e.g.:
  845. # proc fun() {.importc: "$1aux".} => cname = funaux
  846. constraint*: PNode # additional constraints like 'lit|result'; also
  847. # misused for the codegenDecl pragma in the hope
  848. # it won't cause problems
  849. # for skModule the string literal to output for
  850. # deprecated modules.
  851. when defined(nimsuggest):
  852. allUsages*: seq[TLineInfo]
  853. TTypeSeq* = seq[PType]
  854. TLockLevel* = distinct int16
  855. TTypeAttachedOp* = enum ## as usual, order is important here
  856. attachedDestructor,
  857. attachedAsgn,
  858. attachedSink,
  859. attachedTrace,
  860. attachedDeepCopy
  861. TType* {.acyclic.} = object of TIdObj # \
  862. # types are identical iff they have the
  863. # same id; there may be multiple copies of a type
  864. # in memory!
  865. # Keep in sync with PackedType
  866. kind*: TTypeKind # kind of type
  867. callConv*: TCallingConvention # for procs
  868. flags*: TTypeFlags # flags of the type
  869. sons*: TTypeSeq # base types, etc.
  870. n*: PNode # node for types:
  871. # for range types a nkRange node
  872. # for record types a nkRecord node
  873. # for enum types a list of symbols
  874. # if kind == tyInt: it is an 'int literal(x)' type
  875. # for procs and tyGenericBody, it's the
  876. # formal param list
  877. # for concepts, the concept body
  878. # else: unused
  879. owner*: PSym # the 'owner' of the type
  880. sym*: PSym # types have the sym associated with them
  881. # it is used for converting types to strings
  882. size*: BiggestInt # the size of the type in bytes
  883. # -1 means that the size is unkwown
  884. align*: int16 # the type's alignment requirements
  885. paddingAtEnd*: int16 #
  886. lockLevel*: TLockLevel # lock level as required for deadlock checking
  887. loc*: TLoc
  888. typeInst*: PType # for generic instantiations the tyGenericInst that led to this
  889. # type.
  890. uniqueId*: ItemId # due to a design mistake, we need to keep the real ID here as it
  891. # is required by the --incremental:on mode.
  892. TPair* = object
  893. key*, val*: RootRef
  894. TPairSeq* = seq[TPair]
  895. TIdPair* = object
  896. key*: PIdObj
  897. val*: RootRef
  898. TIdPairSeq* = seq[TIdPair]
  899. TIdTable* = object # the same as table[PIdent] of PObject
  900. counter*: int
  901. data*: TIdPairSeq
  902. TIdNodePair* = object
  903. key*: PIdObj
  904. val*: PNode
  905. TIdNodePairSeq* = seq[TIdNodePair]
  906. TIdNodeTable* = object # the same as table[PIdObj] of PNode
  907. counter*: int
  908. data*: TIdNodePairSeq
  909. TNodePair* = object
  910. h*: Hash # because it is expensive to compute!
  911. key*: PNode
  912. val*: int
  913. TNodePairSeq* = seq[TNodePair]
  914. TNodeTable* = object # the same as table[PNode] of int;
  915. # nodes are compared by structure!
  916. counter*: int
  917. data*: TNodePairSeq
  918. TObjectSeq* = seq[RootRef]
  919. TObjectSet* = object
  920. counter*: int
  921. data*: TObjectSeq
  922. TImplication* = enum
  923. impUnknown, impNo, impYes
  924. template nodeId(n: PNode): int = cast[int](n)
  925. type Gconfig = object
  926. # we put comments in a side channel to avoid increasing `sizeof(TNode)`, which
  927. # reduces memory usage given that `PNode` is the most allocated type by far.
  928. comments: Table[int, string] # nodeId => comment
  929. useIc*: bool
  930. var gconfig {.threadvar.}: Gconfig
  931. proc setUseIc*(useIc: bool) = gconfig.useIc = useIc
  932. proc comment*(n: PNode): string =
  933. if nfHasComment in n.flags and not gconfig.useIc:
  934. # IC doesn't track comments, see `packed_ast`, so this could fail
  935. result = gconfig.comments[n.nodeId]
  936. proc `comment=`*(n: PNode, a: string) =
  937. let id = n.nodeId
  938. if a.len > 0:
  939. # if needed, we could periodically cleanup gconfig.comments when its size increases,
  940. # to ensure only live nodes (and with nfHasComment) have an entry in gconfig.comments;
  941. # for compiling compiler, the waste is very small:
  942. # num calls to newNodeImpl: 14984160 (num of PNode allocations)
  943. # size of gconfig.comments: 33585
  944. # num of nodes with comments that were deleted and hence wasted: 3081
  945. n.flags.incl nfHasComment
  946. gconfig.comments[id] = a
  947. elif nfHasComment in n.flags:
  948. n.flags.excl nfHasComment
  949. gconfig.comments.del(id)
  950. # BUGFIX: a module is overloadable so that a proc can have the
  951. # same name as an imported module. This is necessary because of
  952. # the poor naming choices in the standard library.
  953. const
  954. OverloadableSyms* = {skProc, skFunc, skMethod, skIterator,
  955. skConverter, skModule, skTemplate, skMacro, skEnumField}
  956. GenericTypes*: TTypeKinds = {tyGenericInvocation, tyGenericBody,
  957. tyGenericParam}
  958. StructuralEquivTypes*: TTypeKinds = {tyNil, tyTuple, tyArray,
  959. tySet, tyRange, tyPtr, tyRef, tyVar, tyLent, tySequence, tyProc, tyOpenArray,
  960. tyVarargs}
  961. ConcreteTypes*: TTypeKinds = { # types of the expr that may occur in::
  962. # var x = expr
  963. tyBool, tyChar, tyEnum, tyArray, tyObject,
  964. tySet, tyTuple, tyRange, tyPtr, tyRef, tyVar, tyLent, tySequence, tyProc,
  965. tyPointer,
  966. tyOpenArray, tyString, tyCstring, tyInt..tyInt64, tyFloat..tyFloat128,
  967. tyUInt..tyUInt64}
  968. IntegralTypes* = {tyBool, tyChar, tyEnum, tyInt..tyInt64,
  969. tyFloat..tyFloat128, tyUInt..tyUInt64} # weird name because it contains tyFloat
  970. ConstantDataTypes*: TTypeKinds = {tyArray, tySet,
  971. tyTuple, tySequence}
  972. NilableTypes*: TTypeKinds = {tyPointer, tyCstring, tyRef, tyPtr,
  973. tyProc, tyError} # TODO
  974. PtrLikeKinds*: TTypeKinds = {tyPointer, tyPtr} # for VM
  975. PersistentNodeFlags*: TNodeFlags = {nfBase2, nfBase8, nfBase16,
  976. nfDotSetter, nfDotField,
  977. nfIsRef, nfIsPtr, nfPreventCg, nfLL,
  978. nfFromTemplate, nfDefaultRefsParam,
  979. nfExecuteOnReload, nfLastRead,
  980. nfFirstWrite}
  981. namePos* = 0
  982. patternPos* = 1 # empty except for term rewriting macros
  983. genericParamsPos* = 2
  984. paramsPos* = 3
  985. pragmasPos* = 4
  986. miscPos* = 5 # used for undocumented and hacky stuff
  987. bodyPos* = 6 # position of body; use rodread.getBody() instead!
  988. resultPos* = 7
  989. dispatcherPos* = 8
  990. nfAllFieldsSet* = nfBase2
  991. nkCallKinds* = {nkCall, nkInfix, nkPrefix, nkPostfix,
  992. nkCommand, nkCallStrLit, nkHiddenCallConv}
  993. nkIdentKinds* = {nkIdent, nkSym, nkAccQuoted, nkOpenSymChoice,
  994. nkClosedSymChoice}
  995. nkPragmaCallKinds* = {nkExprColonExpr, nkCall, nkCallStrLit}
  996. nkLiterals* = {nkCharLit..nkTripleStrLit}
  997. nkFloatLiterals* = {nkFloatLit..nkFloat128Lit}
  998. nkLambdaKinds* = {nkLambda, nkDo}
  999. declarativeDefs* = {nkProcDef, nkFuncDef, nkMethodDef, nkIteratorDef, nkConverterDef}
  1000. routineDefs* = declarativeDefs + {nkMacroDef, nkTemplateDef}
  1001. procDefs* = nkLambdaKinds + declarativeDefs
  1002. callableDefs* = nkLambdaKinds + routineDefs
  1003. nkSymChoices* = {nkClosedSymChoice, nkOpenSymChoice}
  1004. nkStrKinds* = {nkStrLit..nkTripleStrLit}
  1005. skLocalVars* = {skVar, skLet, skForVar, skParam, skResult}
  1006. skProcKinds* = {skProc, skFunc, skTemplate, skMacro, skIterator,
  1007. skMethod, skConverter}
  1008. defaultSize = -1
  1009. defaultAlignment = -1
  1010. defaultOffset* = -1
  1011. proc getPIdent*(a: PNode): PIdent {.inline.} =
  1012. ## Returns underlying `PIdent` for `{nkSym, nkIdent}`, or `nil`.
  1013. # xxx consider whether also returning the 1st ident for {nkOpenSymChoice, nkClosedSymChoice}
  1014. # which may simplify code.
  1015. case a.kind
  1016. of nkSym: a.sym.name
  1017. of nkIdent: a.ident
  1018. else: nil
  1019. const
  1020. moduleShift = when defined(cpu32): 20 else: 24
  1021. template id*(a: PIdObj): int =
  1022. let x = a
  1023. (x.itemId.module.int shl moduleShift) + x.itemId.item.int
  1024. type
  1025. IdGenerator* = ref object # unfortunately, we really need the 'shared mutable' aspect here.
  1026. module*: int32
  1027. symId*: int32
  1028. typeId*: int32
  1029. sealed*: bool
  1030. const
  1031. PackageModuleId* = -3'i32
  1032. proc idGeneratorFromModule*(m: PSym): IdGenerator =
  1033. assert m.kind == skModule
  1034. result = IdGenerator(module: m.itemId.module, symId: m.itemId.item, typeId: 0)
  1035. proc nextSymId*(x: IdGenerator): ItemId {.inline.} =
  1036. assert(not x.sealed)
  1037. inc x.symId
  1038. result = ItemId(module: x.module, item: x.symId)
  1039. proc nextTypeId*(x: IdGenerator): ItemId {.inline.} =
  1040. assert(not x.sealed)
  1041. inc x.typeId
  1042. result = ItemId(module: x.module, item: x.typeId)
  1043. when false:
  1044. proc nextId*(x: IdGenerator): ItemId {.inline.} =
  1045. inc x.item
  1046. result = x[]
  1047. when false:
  1048. proc storeBack*(dest: var IdGenerator; src: IdGenerator) {.inline.} =
  1049. assert dest.ItemId.module == src.ItemId.module
  1050. if dest.ItemId.item > src.ItemId.item:
  1051. echo dest.ItemId.item, " ", src.ItemId.item, " ", src.ItemId.module
  1052. assert dest.ItemId.item <= src.ItemId.item
  1053. dest = src
  1054. var ggDebug* {.deprecated.}: bool ## convenience switch for trying out things
  1055. proc isCallExpr*(n: PNode): bool =
  1056. result = n.kind in nkCallKinds
  1057. proc discardSons*(father: PNode)
  1058. type Indexable = PNode | PType
  1059. proc len*(n: Indexable): int {.inline.} =
  1060. result = n.sons.len
  1061. proc safeLen*(n: PNode): int {.inline.} =
  1062. ## works even for leaves.
  1063. if n.kind in {nkNone..nkNilLit}: result = 0
  1064. else: result = n.len
  1065. proc safeArrLen*(n: PNode): int {.inline.} =
  1066. ## works for array-like objects (strings passed as openArray in VM).
  1067. if n.kind in {nkStrLit..nkTripleStrLit}: result = n.strVal.len
  1068. elif n.kind in {nkNone..nkFloat128Lit}: result = 0
  1069. else: result = n.len
  1070. proc add*(father, son: Indexable) =
  1071. assert son != nil
  1072. father.sons.add(son)
  1073. proc addAllowNil*(father, son: Indexable) {.inline.} =
  1074. father.sons.add(son)
  1075. template `[]`*(n: Indexable, i: int): Indexable = n.sons[i]
  1076. template `[]=`*(n: Indexable, i: int; x: Indexable) = n.sons[i] = x
  1077. template `[]`*(n: Indexable, i: BackwardsIndex): Indexable = n[n.len - i.int]
  1078. template `[]=`*(n: Indexable, i: BackwardsIndex; x: Indexable) = n[n.len - i.int] = x
  1079. proc getDeclPragma*(n: PNode): PNode =
  1080. ## return the `nkPragma` node for declaration `n`, or `nil` if no pragma was found.
  1081. ## Currently only supports routineDefs + {nkTypeDef}.
  1082. case n.kind
  1083. of routineDefs:
  1084. if n[pragmasPos].kind != nkEmpty: result = n[pragmasPos]
  1085. of nkTypeDef:
  1086. #[
  1087. type F3*{.deprecated: "x3".} = int
  1088. TypeSection
  1089. TypeDef
  1090. PragmaExpr
  1091. Postfix
  1092. Ident "*"
  1093. Ident "F3"
  1094. Pragma
  1095. ExprColonExpr
  1096. Ident "deprecated"
  1097. StrLit "x3"
  1098. Empty
  1099. Ident "int"
  1100. ]#
  1101. if n[0].kind == nkPragmaExpr:
  1102. result = n[0][1]
  1103. else:
  1104. # support as needed for `nkIdentDefs` etc.
  1105. result = nil
  1106. if result != nil:
  1107. assert result.kind == nkPragma, $(result.kind, n.kind)
  1108. proc extractPragma*(s: PSym): PNode =
  1109. ## gets the pragma node of routine/type/var/let/const symbol `s`
  1110. if s.kind in routineKinds:
  1111. result = s.ast[pragmasPos]
  1112. elif s.kind in {skType, skVar, skLet, skConst}:
  1113. if s.ast != nil and s.ast.len > 0:
  1114. if s.ast[0].kind == nkPragmaExpr and s.ast[0].len > 1:
  1115. # s.ast = nkTypedef / nkPragmaExpr / [nkSym, nkPragma]
  1116. result = s.ast[0][1]
  1117. assert result == nil or result.kind == nkPragma
  1118. proc skipPragmaExpr*(n: PNode): PNode =
  1119. ## if pragma expr, give the node the pragmas are applied to,
  1120. ## otherwise give node itself
  1121. if n.kind == nkPragmaExpr:
  1122. result = n[0]
  1123. else:
  1124. result = n
  1125. proc setInfoRecursive*(n: PNode, info: TLineInfo) =
  1126. ## set line info recursively
  1127. if n != nil:
  1128. for i in 0..<n.safeLen: setInfoRecursive(n[i], info)
  1129. n.info = info
  1130. when defined(useNodeIds):
  1131. const nodeIdToDebug* = -1 # 2322968
  1132. var gNodeId: int
  1133. template newNodeImpl(info2) =
  1134. result = PNode(kind: kind, info: info2)
  1135. when false:
  1136. # this would add overhead, so we skip it; it results in a small amount of leaked entries
  1137. # for old PNode that gets re-allocated at the same address as a PNode that
  1138. # has `nfHasComment` set (and an entry in that table). Only `nfHasComment`
  1139. # should be used to test whether a PNode has a comment; gconfig.comments
  1140. # can contain extra entries for deleted PNode's with comments.
  1141. gconfig.comments.del(cast[int](result))
  1142. template setIdMaybe() =
  1143. when defined(useNodeIds):
  1144. result.id = gNodeId
  1145. if result.id == nodeIdToDebug:
  1146. echo "KIND ", result.kind
  1147. writeStackTrace()
  1148. inc gNodeId
  1149. proc newNode*(kind: TNodeKind): PNode =
  1150. ## new node with unknown line info, no type, and no children
  1151. newNodeImpl(unknownLineInfo)
  1152. setIdMaybe()
  1153. proc newNodeI*(kind: TNodeKind, info: TLineInfo): PNode =
  1154. ## new node with line info, no type, and no children
  1155. newNodeImpl(info)
  1156. setIdMaybe()
  1157. proc newNodeI*(kind: TNodeKind, info: TLineInfo, children: int): PNode =
  1158. ## new node with line info, type, and children
  1159. newNodeImpl(info)
  1160. if children > 0:
  1161. newSeq(result.sons, children)
  1162. setIdMaybe()
  1163. proc newNodeIT*(kind: TNodeKind, info: TLineInfo, typ: PType): PNode =
  1164. ## new node with line info, type, and no children
  1165. result = newNode(kind)
  1166. result.info = info
  1167. result.typ = typ
  1168. proc newTree*(kind: TNodeKind; children: varargs[PNode]): PNode =
  1169. result = newNode(kind)
  1170. if children.len > 0:
  1171. result.info = children[0].info
  1172. result.sons = @children
  1173. proc newTreeI*(kind: TNodeKind; info: TLineInfo; children: varargs[PNode]): PNode =
  1174. result = newNodeI(kind, info)
  1175. if children.len > 0:
  1176. result.info = children[0].info
  1177. result.sons = @children
  1178. proc newTreeIT*(kind: TNodeKind; info: TLineInfo; typ: PType; children: varargs[PNode]): PNode =
  1179. result = newNodeIT(kind, info, typ)
  1180. if children.len > 0:
  1181. result.info = children[0].info
  1182. result.sons = @children
  1183. template previouslyInferred*(t: PType): PType =
  1184. if t.sons.len > 1: t.lastSon else: nil
  1185. when false:
  1186. import tables, strutils
  1187. var x: CountTable[string]
  1188. addQuitProc proc () {.noconv.} =
  1189. for k, v in pairs(x):
  1190. echo k
  1191. echo v
  1192. proc newSym*(symKind: TSymKind, name: PIdent, id: ItemId, owner: PSym,
  1193. info: TLineInfo; options: TOptions = {}): PSym =
  1194. # generates a symbol and initializes the hash field too
  1195. result = PSym(name: name, kind: symKind, flags: {}, info: info, itemId: id,
  1196. options: options, owner: owner, offset: defaultOffset)
  1197. when false:
  1198. if id.module == 48 and id.item == 39:
  1199. writeStackTrace()
  1200. echo "kind ", symKind, " ", name.s
  1201. if owner != nil: echo owner.name.s
  1202. proc astdef*(s: PSym): PNode =
  1203. # get only the definition (initializer) portion of the ast
  1204. if s.ast != nil and s.ast.kind in {nkIdentDefs, nkConstDef}:
  1205. s.ast[2]
  1206. else:
  1207. s.ast
  1208. proc isMetaType*(t: PType): bool =
  1209. return t.kind in tyMetaTypes or
  1210. (t.kind == tyStatic and t.n == nil) or
  1211. tfHasMeta in t.flags
  1212. proc isUnresolvedStatic*(t: PType): bool =
  1213. return t.kind == tyStatic and t.n == nil
  1214. proc linkTo*(t: PType, s: PSym): PType {.discardable.} =
  1215. t.sym = s
  1216. s.typ = t
  1217. result = t
  1218. proc linkTo*(s: PSym, t: PType): PSym {.discardable.} =
  1219. t.sym = s
  1220. s.typ = t
  1221. result = s
  1222. template fileIdx*(c: PSym): FileIndex =
  1223. # XXX: this should be used only on module symbols
  1224. c.position.FileIndex
  1225. template filename*(c: PSym): string =
  1226. # XXX: this should be used only on module symbols
  1227. c.position.FileIndex.toFilename
  1228. proc appendToModule*(m: PSym, n: PNode) =
  1229. ## The compiler will use this internally to add nodes that will be
  1230. ## appended to the module after the sem pass
  1231. if m.ast == nil:
  1232. m.ast = newNode(nkStmtList)
  1233. m.ast.sons = @[n]
  1234. else:
  1235. assert m.ast.kind == nkStmtList
  1236. m.ast.sons.add(n)
  1237. const # for all kind of hash tables:
  1238. GrowthFactor* = 2 # must be power of 2, > 0
  1239. StartSize* = 8 # must be power of 2, > 0
  1240. proc copyStrTable*(dest: var TStrTable, src: TStrTable) =
  1241. dest.counter = src.counter
  1242. setLen(dest.data, src.data.len)
  1243. for i in 0..high(src.data): dest.data[i] = src.data[i]
  1244. proc copyIdTable*(dest: var TIdTable, src: TIdTable) =
  1245. dest.counter = src.counter
  1246. newSeq(dest.data, src.data.len)
  1247. for i in 0..high(src.data): dest.data[i] = src.data[i]
  1248. proc copyObjectSet*(dest: var TObjectSet, src: TObjectSet) =
  1249. dest.counter = src.counter
  1250. setLen(dest.data, src.data.len)
  1251. for i in 0..high(src.data): dest.data[i] = src.data[i]
  1252. proc discardSons*(father: PNode) =
  1253. father.sons = @[]
  1254. proc withInfo*(n: PNode, info: TLineInfo): PNode =
  1255. n.info = info
  1256. return n
  1257. proc newIdentNode*(ident: PIdent, info: TLineInfo): PNode =
  1258. result = newNode(nkIdent)
  1259. result.ident = ident
  1260. result.info = info
  1261. proc newSymNode*(sym: PSym): PNode =
  1262. result = newNode(nkSym)
  1263. result.sym = sym
  1264. result.typ = sym.typ
  1265. result.info = sym.info
  1266. proc newSymNode*(sym: PSym, info: TLineInfo): PNode =
  1267. result = newNode(nkSym)
  1268. result.sym = sym
  1269. result.typ = sym.typ
  1270. result.info = info
  1271. proc newIntNode*(kind: TNodeKind, intVal: BiggestInt): PNode =
  1272. result = newNode(kind)
  1273. result.intVal = intVal
  1274. proc newIntNode*(kind: TNodeKind, intVal: Int128): PNode =
  1275. result = newNode(kind)
  1276. result.intVal = castToInt64(intVal)
  1277. proc lastSon*(n: Indexable): Indexable = n.sons[^1]
  1278. proc skipTypes*(t: PType, kinds: TTypeKinds): PType =
  1279. ## Used throughout the compiler code to test whether a type tree contains or
  1280. ## doesn't contain a specific type/types - it is often the case that only the
  1281. ## last child nodes of a type tree need to be searched. This is a really hot
  1282. ## path within the compiler!
  1283. result = t
  1284. while result.kind in kinds: result = lastSon(result)
  1285. proc newIntTypeNode*(intVal: BiggestInt, typ: PType): PNode =
  1286. let kind = skipTypes(typ, abstractVarRange).kind
  1287. case kind
  1288. of tyInt: result = newNode(nkIntLit)
  1289. of tyInt8: result = newNode(nkInt8Lit)
  1290. of tyInt16: result = newNode(nkInt16Lit)
  1291. of tyInt32: result = newNode(nkInt32Lit)
  1292. of tyInt64: result = newNode(nkInt64Lit)
  1293. of tyChar: result = newNode(nkCharLit)
  1294. of tyUInt: result = newNode(nkUIntLit)
  1295. of tyUInt8: result = newNode(nkUInt8Lit)
  1296. of tyUInt16: result = newNode(nkUInt16Lit)
  1297. of tyUInt32: result = newNode(nkUInt32Lit)
  1298. of tyUInt64: result = newNode(nkUInt64Lit)
  1299. of tyBool, tyEnum:
  1300. # XXX: does this really need to be the kind nkIntLit?
  1301. result = newNode(nkIntLit)
  1302. of tyStatic: # that's a pre-existing bug, will fix in another PR
  1303. result = newNode(nkIntLit)
  1304. else: doAssert false, $kind
  1305. result.intVal = intVal
  1306. result.typ = typ
  1307. proc newIntTypeNode*(intVal: Int128, typ: PType): PNode =
  1308. # XXX: introduce range check
  1309. newIntTypeNode(castToInt64(intVal), typ)
  1310. proc newFloatNode*(kind: TNodeKind, floatVal: BiggestFloat): PNode =
  1311. result = newNode(kind)
  1312. result.floatVal = floatVal
  1313. proc newStrNode*(kind: TNodeKind, strVal: string): PNode =
  1314. result = newNode(kind)
  1315. result.strVal = strVal
  1316. proc newStrNode*(strVal: string; info: TLineInfo): PNode =
  1317. result = newNodeI(nkStrLit, info)
  1318. result.strVal = strVal
  1319. proc newProcNode*(kind: TNodeKind, info: TLineInfo, body: PNode,
  1320. params,
  1321. name, pattern, genericParams,
  1322. pragmas, exceptions: PNode): PNode =
  1323. result = newNodeI(kind, info)
  1324. result.sons = @[name, pattern, genericParams, params,
  1325. pragmas, exceptions, body]
  1326. const
  1327. UnspecifiedLockLevel* = TLockLevel(-1'i16)
  1328. MaxLockLevel* = 1000'i16
  1329. UnknownLockLevel* = TLockLevel(1001'i16)
  1330. AttachedOpToStr*: array[TTypeAttachedOp, string] = [
  1331. "=destroy", "=copy", "=sink", "=trace", "=deepcopy"]
  1332. proc `$`*(x: TLockLevel): string =
  1333. if x.ord == UnspecifiedLockLevel.ord: result = "<unspecified>"
  1334. elif x.ord == UnknownLockLevel.ord: result = "<unknown>"
  1335. else: result = $int16(x)
  1336. proc `$`*(s: PSym): string =
  1337. if s != nil:
  1338. result = s.name.s & "@" & $s.id
  1339. else:
  1340. result = "<nil>"
  1341. proc newType*(kind: TTypeKind, id: ItemId; owner: PSym): PType =
  1342. result = PType(kind: kind, owner: owner, size: defaultSize,
  1343. align: defaultAlignment, itemId: id,
  1344. lockLevel: UnspecifiedLockLevel,
  1345. uniqueId: id)
  1346. when false:
  1347. if result.itemId.module == 55 and result.itemId.item == 2:
  1348. echo "KNID ", kind
  1349. writeStackTrace()
  1350. proc mergeLoc(a: var TLoc, b: TLoc) =
  1351. if a.k == low(typeof(a.k)): a.k = b.k
  1352. if a.storage == low(typeof(a.storage)): a.storage = b.storage
  1353. a.flags.incl b.flags
  1354. if a.lode == nil: a.lode = b.lode
  1355. if a.r == "": a.r = b.r
  1356. proc newSons*(father: Indexable, length: int) =
  1357. setLen(father.sons, length)
  1358. proc assignType*(dest, src: PType) =
  1359. dest.kind = src.kind
  1360. dest.flags = src.flags
  1361. dest.callConv = src.callConv
  1362. dest.n = src.n
  1363. dest.size = src.size
  1364. dest.align = src.align
  1365. dest.lockLevel = src.lockLevel
  1366. # this fixes 'type TLock = TSysLock':
  1367. if src.sym != nil:
  1368. if dest.sym != nil:
  1369. dest.sym.flags.incl src.sym.flags-{sfUsed, sfExported}
  1370. if dest.sym.annex == nil: dest.sym.annex = src.sym.annex
  1371. mergeLoc(dest.sym.loc, src.sym.loc)
  1372. else:
  1373. dest.sym = src.sym
  1374. newSons(dest, src.len)
  1375. for i in 0..<src.len: dest[i] = src[i]
  1376. proc copyType*(t: PType, id: ItemId, owner: PSym): PType =
  1377. result = newType(t.kind, id, owner)
  1378. assignType(result, t)
  1379. result.sym = t.sym # backend-info should not be copied
  1380. proc exactReplica*(t: PType): PType =
  1381. result = copyType(t, t.itemId, t.owner)
  1382. proc copySym*(s: PSym; id: ItemId): PSym =
  1383. result = newSym(s.kind, s.name, id, s.owner, s.info, s.options)
  1384. #result.ast = nil # BUGFIX; was: s.ast which made problems
  1385. result.typ = s.typ
  1386. result.flags = s.flags
  1387. result.magic = s.magic
  1388. result.options = s.options
  1389. result.position = s.position
  1390. result.loc = s.loc
  1391. result.annex = s.annex # BUGFIX
  1392. result.constraint = s.constraint
  1393. if result.kind in {skVar, skLet, skField}:
  1394. result.guard = s.guard
  1395. result.bitsize = s.bitsize
  1396. result.alignment = s.alignment
  1397. proc createModuleAlias*(s: PSym, id: ItemId, newIdent: PIdent, info: TLineInfo;
  1398. options: TOptions): PSym =
  1399. result = newSym(s.kind, newIdent, id, s.owner, info, options)
  1400. # keep ID!
  1401. result.ast = s.ast
  1402. #result.id = s.id # XXX figure out what to do with the ID.
  1403. result.flags = s.flags
  1404. result.options = s.options
  1405. result.position = s.position
  1406. result.loc = s.loc
  1407. result.annex = s.annex
  1408. proc initStrTable*(x: var TStrTable) =
  1409. x.counter = 0
  1410. newSeq(x.data, StartSize)
  1411. proc newStrTable*: TStrTable =
  1412. initStrTable(result)
  1413. proc initIdTable*(x: var TIdTable) =
  1414. x.counter = 0
  1415. newSeq(x.data, StartSize)
  1416. proc newIdTable*: TIdTable =
  1417. initIdTable(result)
  1418. proc resetIdTable*(x: var TIdTable) =
  1419. x.counter = 0
  1420. # clear and set to old initial size:
  1421. setLen(x.data, 0)
  1422. setLen(x.data, StartSize)
  1423. proc initObjectSet*(x: var TObjectSet) =
  1424. x.counter = 0
  1425. newSeq(x.data, StartSize)
  1426. proc initIdNodeTable*(x: var TIdNodeTable) =
  1427. x.counter = 0
  1428. newSeq(x.data, StartSize)
  1429. proc initNodeTable*(x: var TNodeTable) =
  1430. x.counter = 0
  1431. newSeq(x.data, StartSize)
  1432. proc skipTypes*(t: PType, kinds: TTypeKinds; maxIters: int): PType =
  1433. result = t
  1434. var i = maxIters
  1435. while result.kind in kinds:
  1436. result = lastSon(result)
  1437. dec i
  1438. if i == 0: return nil
  1439. proc skipTypesOrNil*(t: PType, kinds: TTypeKinds): PType =
  1440. ## same as skipTypes but handles 'nil'
  1441. result = t
  1442. while result != nil and result.kind in kinds:
  1443. if result.len == 0: return nil
  1444. result = lastSon(result)
  1445. proc isGCedMem*(t: PType): bool {.inline.} =
  1446. result = t.kind in {tyString, tyRef, tySequence} or
  1447. t.kind == tyProc and t.callConv == ccClosure
  1448. proc propagateToOwner*(owner, elem: PType; propagateHasAsgn = true) =
  1449. owner.flags.incl elem.flags * {tfHasMeta, tfTriggersCompileTime}
  1450. if tfNotNil in elem.flags:
  1451. if owner.kind in {tyGenericInst, tyGenericBody, tyGenericInvocation}:
  1452. owner.flags.incl tfNotNil
  1453. if elem.isMetaType:
  1454. owner.flags.incl tfHasMeta
  1455. let mask = elem.flags * {tfHasAsgn, tfHasOwned}
  1456. if mask != {} and propagateHasAsgn:
  1457. let o2 = owner.skipTypes({tyGenericInst, tyAlias, tySink})
  1458. if o2.kind in {tyTuple, tyObject, tyArray,
  1459. tySequence, tySet, tyDistinct}:
  1460. o2.flags.incl mask
  1461. owner.flags.incl mask
  1462. if owner.kind notin {tyProc, tyGenericInst, tyGenericBody,
  1463. tyGenericInvocation, tyPtr}:
  1464. let elemB = elem.skipTypes({tyGenericInst, tyAlias, tySink})
  1465. if elemB.isGCedMem or tfHasGCedMem in elemB.flags:
  1466. # for simplicity, we propagate this flag even to generics. We then
  1467. # ensure this doesn't bite us in sempass2.
  1468. owner.flags.incl tfHasGCedMem
  1469. proc rawAddSon*(father, son: PType; propagateHasAsgn = true) =
  1470. father.sons.add(son)
  1471. if not son.isNil: propagateToOwner(father, son, propagateHasAsgn)
  1472. proc rawAddSonNoPropagationOfTypeFlags*(father, son: PType) =
  1473. father.sons.add(son)
  1474. proc addSonNilAllowed*(father, son: PNode) =
  1475. father.sons.add(son)
  1476. proc delSon*(father: PNode, idx: int) =
  1477. if father.len == 0: return
  1478. for i in idx..<father.len - 1: father[i] = father[i + 1]
  1479. father.sons.setLen(father.len - 1)
  1480. proc copyNode*(src: PNode): PNode =
  1481. # does not copy its sons!
  1482. if src == nil:
  1483. return nil
  1484. result = newNode(src.kind)
  1485. result.info = src.info
  1486. result.typ = src.typ
  1487. result.flags = src.flags * PersistentNodeFlags
  1488. result.comment = src.comment
  1489. when defined(useNodeIds):
  1490. if result.id == nodeIdToDebug:
  1491. echo "COMES FROM ", src.id
  1492. case src.kind
  1493. of nkCharLit..nkUInt64Lit: result.intVal = src.intVal
  1494. of nkFloatLiterals: result.floatVal = src.floatVal
  1495. of nkSym: result.sym = src.sym
  1496. of nkIdent: result.ident = src.ident
  1497. of nkStrLit..nkTripleStrLit: result.strVal = src.strVal
  1498. else: discard
  1499. template transitionNodeKindCommon(k: TNodeKind) =
  1500. let obj {.inject.} = n[]
  1501. n[] = TNode(kind: k, typ: obj.typ, info: obj.info, flags: obj.flags)
  1502. # n.comment = obj.comment # shouldn't be needed, the address doesnt' change
  1503. when defined(useNodeIds):
  1504. n.id = obj.id
  1505. proc transitionSonsKind*(n: PNode, kind: range[nkComesFrom..nkTupleConstr]) =
  1506. transitionNodeKindCommon(kind)
  1507. n.sons = obj.sons
  1508. proc transitionIntKind*(n: PNode, kind: range[nkCharLit..nkUInt64Lit]) =
  1509. transitionNodeKindCommon(kind)
  1510. n.intVal = obj.intVal
  1511. proc transitionIntToFloatKind*(n: PNode, kind: range[nkFloatLit..nkFloat128Lit]) =
  1512. transitionNodeKindCommon(kind)
  1513. n.floatVal = BiggestFloat(obj.intVal)
  1514. proc transitionNoneToSym*(n: PNode) =
  1515. transitionNodeKindCommon(nkSym)
  1516. template transitionSymKindCommon*(k: TSymKind) =
  1517. let obj {.inject.} = s[]
  1518. s[] = TSym(kind: k, itemId: obj.itemId, magic: obj.magic, typ: obj.typ, name: obj.name,
  1519. info: obj.info, owner: obj.owner, flags: obj.flags, ast: obj.ast,
  1520. options: obj.options, position: obj.position, offset: obj.offset,
  1521. loc: obj.loc, annex: obj.annex, constraint: obj.constraint)
  1522. when hasFFI:
  1523. s.cname = obj.cname
  1524. when defined(nimsuggest):
  1525. s.allUsages = obj.allUsages
  1526. proc transitionGenericParamToType*(s: PSym) =
  1527. transitionSymKindCommon(skType)
  1528. proc transitionRoutineSymKind*(s: PSym, kind: range[skProc..skTemplate]) =
  1529. transitionSymKindCommon(kind)
  1530. s.gcUnsafetyReason = obj.gcUnsafetyReason
  1531. s.transformedBody = obj.transformedBody
  1532. proc transitionToLet*(s: PSym) =
  1533. transitionSymKindCommon(skLet)
  1534. s.guard = obj.guard
  1535. s.bitsize = obj.bitsize
  1536. s.alignment = obj.alignment
  1537. template copyNodeImpl(dst, src, processSonsStmt) =
  1538. if src == nil: return
  1539. dst = newNode(src.kind)
  1540. dst.info = src.info
  1541. dst.typ = src.typ
  1542. dst.flags = src.flags * PersistentNodeFlags
  1543. dst.comment = src.comment
  1544. when defined(useNodeIds):
  1545. if dst.id == nodeIdToDebug:
  1546. echo "COMES FROM ", src.id
  1547. case src.kind
  1548. of nkCharLit..nkUInt64Lit: dst.intVal = src.intVal
  1549. of nkFloatLiterals: dst.floatVal = src.floatVal
  1550. of nkSym: dst.sym = src.sym
  1551. of nkIdent: dst.ident = src.ident
  1552. of nkStrLit..nkTripleStrLit: dst.strVal = src.strVal
  1553. else: processSonsStmt
  1554. proc shallowCopy*(src: PNode): PNode =
  1555. # does not copy its sons, but provides space for them:
  1556. copyNodeImpl(result, src):
  1557. newSeq(result.sons, src.len)
  1558. proc copyTree*(src: PNode): PNode =
  1559. # copy a whole syntax tree; performs deep copying
  1560. copyNodeImpl(result, src):
  1561. newSeq(result.sons, src.len)
  1562. for i in 0..<src.len:
  1563. result[i] = copyTree(src[i])
  1564. proc copyTreeWithoutNode*(src, skippedNode: PNode): PNode =
  1565. copyNodeImpl(result, src):
  1566. result.sons = newSeqOfCap[PNode](src.len)
  1567. for n in src.sons:
  1568. if n != skippedNode:
  1569. result.sons.add copyTreeWithoutNode(n, skippedNode)
  1570. proc hasSonWith*(n: PNode, kind: TNodeKind): bool =
  1571. for i in 0..<n.len:
  1572. if n[i].kind == kind:
  1573. return true
  1574. result = false
  1575. proc hasNilSon*(n: PNode): bool =
  1576. for i in 0..<n.safeLen:
  1577. if n[i] == nil:
  1578. return true
  1579. elif hasNilSon(n[i]):
  1580. return true
  1581. result = false
  1582. proc containsNode*(n: PNode, kinds: TNodeKinds): bool =
  1583. if n == nil: return
  1584. case n.kind
  1585. of nkEmpty..nkNilLit: result = n.kind in kinds
  1586. else:
  1587. for i in 0..<n.len:
  1588. if n.kind in kinds or containsNode(n[i], kinds): return true
  1589. proc hasSubnodeWith*(n: PNode, kind: TNodeKind): bool =
  1590. case n.kind
  1591. of nkEmpty..nkNilLit, nkFormalParams: result = n.kind == kind
  1592. else:
  1593. for i in 0..<n.len:
  1594. if (n[i].kind == kind) or hasSubnodeWith(n[i], kind):
  1595. return true
  1596. result = false
  1597. proc getInt*(a: PNode): Int128 =
  1598. case a.kind
  1599. of nkCharLit, nkUIntLit..nkUInt64Lit:
  1600. result = toInt128(cast[uint64](a.intVal))
  1601. of nkInt8Lit..nkInt64Lit:
  1602. result = toInt128(a.intVal)
  1603. of nkIntLit:
  1604. # XXX: enable this assert
  1605. # assert a.typ.kind notin {tyChar, tyUint..tyUInt64}
  1606. result = toInt128(a.intVal)
  1607. else:
  1608. raiseRecoverableError("cannot extract number from invalid AST node")
  1609. proc getInt64*(a: PNode): int64 {.deprecated: "use getInt".} =
  1610. case a.kind
  1611. of nkCharLit, nkUIntLit..nkUInt64Lit, nkIntLit..nkInt64Lit:
  1612. result = a.intVal
  1613. else:
  1614. raiseRecoverableError("cannot extract number from invalid AST node")
  1615. proc getFloat*(a: PNode): BiggestFloat =
  1616. case a.kind
  1617. of nkFloatLiterals: result = a.floatVal
  1618. of nkCharLit, nkUIntLit..nkUInt64Lit, nkIntLit..nkInt64Lit:
  1619. result = BiggestFloat a.intVal
  1620. else:
  1621. raiseRecoverableError("cannot extract number from invalid AST node")
  1622. #doAssert false, "getFloat"
  1623. #internalError(a.info, "getFloat")
  1624. #result = 0.0
  1625. proc getStr*(a: PNode): string =
  1626. case a.kind
  1627. of nkStrLit..nkTripleStrLit: result = a.strVal
  1628. of nkNilLit:
  1629. # let's hope this fixes more problems than it creates:
  1630. result = ""
  1631. else:
  1632. raiseRecoverableError("cannot extract string from invalid AST node")
  1633. #doAssert false, "getStr"
  1634. #internalError(a.info, "getStr")
  1635. #result = ""
  1636. proc getStrOrChar*(a: PNode): string =
  1637. case a.kind
  1638. of nkStrLit..nkTripleStrLit: result = a.strVal
  1639. of nkCharLit..nkUInt64Lit: result = $chr(int(a.intVal))
  1640. else:
  1641. raiseRecoverableError("cannot extract string from invalid AST node")
  1642. #doAssert false, "getStrOrChar"
  1643. #internalError(a.info, "getStrOrChar")
  1644. #result = ""
  1645. proc isGenericParams*(n: PNode): bool {.inline.} =
  1646. ## used to judge whether a node is generic params.
  1647. n != nil and n.kind == nkGenericParams
  1648. proc isGenericRoutine*(n: PNode): bool {.inline.} =
  1649. n != nil and n.kind in callableDefs and n[genericParamsPos].isGenericParams
  1650. proc isGenericRoutineStrict*(s: PSym): bool {.inline.} =
  1651. ## determines if this symbol represents a generic routine
  1652. ## the unusual name is so it doesn't collide and eventually replaces
  1653. ## `isGenericRoutine`
  1654. s.kind in skProcKinds and s.ast.isGenericRoutine
  1655. proc isGenericRoutine*(s: PSym): bool {.inline.} =
  1656. ## determines if this symbol represents a generic routine or an instance of
  1657. ## one. This should be renamed accordingly and `isGenericRoutineStrict`
  1658. ## should take this name instead.
  1659. ##
  1660. ## Warning/XXX: Unfortunately, it considers a proc kind symbol flagged with
  1661. ## sfFromGeneric as a generic routine. Instead this should likely not be the
  1662. ## case and the concepts should be teased apart:
  1663. ## - generic definition
  1664. ## - generic instance
  1665. ## - either generic definition or instance
  1666. s.kind in skProcKinds and (sfFromGeneric in s.flags or
  1667. s.ast.isGenericRoutine)
  1668. proc skipGenericOwner*(s: PSym): PSym =
  1669. ## Generic instantiations are owned by their originating generic
  1670. ## symbol. This proc skips such owners and goes straight to the owner
  1671. ## of the generic itself (the module or the enclosing proc).
  1672. result = if s.kind in skProcKinds and sfFromGeneric in s.flags:
  1673. s.owner.owner
  1674. else:
  1675. s.owner
  1676. proc originatingModule*(s: PSym): PSym =
  1677. result = s.owner
  1678. while result.kind != skModule: result = result.owner
  1679. proc isRoutine*(s: PSym): bool {.inline.} =
  1680. result = s.kind in skProcKinds
  1681. proc isCompileTimeProc*(s: PSym): bool {.inline.} =
  1682. result = s.kind == skMacro or
  1683. s.kind in {skProc, skFunc} and sfCompileTime in s.flags
  1684. proc isRunnableExamples*(n: PNode): bool =
  1685. # Templates and generics don't perform symbol lookups.
  1686. result = n.kind == nkSym and n.sym.magic == mRunnableExamples or
  1687. n.kind == nkIdent and n.ident.s == "runnableExamples"
  1688. proc requiredParams*(s: PSym): int =
  1689. # Returns the number of required params (without default values)
  1690. # XXX: Perhaps we can store this in the `offset` field of the
  1691. # symbol instead?
  1692. for i in 1..<s.typ.len:
  1693. if s.typ.n[i].sym.ast != nil:
  1694. return i - 1
  1695. return s.typ.len - 1
  1696. proc hasPattern*(s: PSym): bool {.inline.} =
  1697. result = isRoutine(s) and s.ast[patternPos].kind != nkEmpty
  1698. iterator items*(n: PNode): PNode =
  1699. for i in 0..<n.safeLen: yield n[i]
  1700. iterator pairs*(n: PNode): tuple[i: int, n: PNode] =
  1701. for i in 0..<n.safeLen: yield (i, n[i])
  1702. proc isAtom*(n: PNode): bool {.inline.} =
  1703. result = n.kind >= nkNone and n.kind <= nkNilLit
  1704. proc isEmptyType*(t: PType): bool {.inline.} =
  1705. ## 'void' and 'typed' types are often equivalent to 'nil' these days:
  1706. result = t == nil or t.kind in {tyVoid, tyTyped}
  1707. proc makeStmtList*(n: PNode): PNode =
  1708. if n.kind == nkStmtList:
  1709. result = n
  1710. else:
  1711. result = newNodeI(nkStmtList, n.info)
  1712. result.add n
  1713. proc skipStmtList*(n: PNode): PNode =
  1714. if n.kind in {nkStmtList, nkStmtListExpr}:
  1715. for i in 0..<n.len-1:
  1716. if n[i].kind notin {nkEmpty, nkCommentStmt}: return n
  1717. result = n.lastSon
  1718. else:
  1719. result = n
  1720. proc toVar*(typ: PType; kind: TTypeKind; idgen: IdGenerator): PType =
  1721. ## If ``typ`` is not a tyVar then it is converted into a `var <typ>` and
  1722. ## returned. Otherwise ``typ`` is simply returned as-is.
  1723. result = typ
  1724. if typ.kind != kind:
  1725. result = newType(kind, nextTypeId(idgen), typ.owner)
  1726. rawAddSon(result, typ)
  1727. proc toRef*(typ: PType; idgen: IdGenerator): PType =
  1728. ## If ``typ`` is a tyObject then it is converted into a `ref <typ>` and
  1729. ## returned. Otherwise ``typ`` is simply returned as-is.
  1730. result = typ
  1731. if typ.skipTypes({tyAlias, tyGenericInst}).kind == tyObject:
  1732. result = newType(tyRef, nextTypeId(idgen), typ.owner)
  1733. rawAddSon(result, typ)
  1734. proc toObject*(typ: PType): PType =
  1735. ## If ``typ`` is a tyRef then its immediate son is returned (which in many
  1736. ## cases should be a ``tyObject``).
  1737. ## Otherwise ``typ`` is simply returned as-is.
  1738. let t = typ.skipTypes({tyAlias, tyGenericInst})
  1739. if t.kind == tyRef: t.lastSon
  1740. else: typ
  1741. proc toObjectFromRefPtrGeneric*(typ: PType): PType =
  1742. #[
  1743. See also `toObject`.
  1744. Finds the underlying `object`, even in cases like these:
  1745. type
  1746. B[T] = object f0: int
  1747. A1[T] = ref B[T]
  1748. A2[T] = ref object f1: int
  1749. A3 = ref object f2: int
  1750. A4 = object f3: int
  1751. ]#
  1752. result = typ
  1753. while true:
  1754. case result.kind
  1755. of tyGenericBody: result = result.lastSon
  1756. of tyRef, tyPtr, tyGenericInst, tyGenericInvocation, tyAlias: result = result[0]
  1757. # automatic dereferencing is deep, refs #18298.
  1758. else: break
  1759. assert result.sym != nil
  1760. proc isImportedException*(t: PType; conf: ConfigRef): bool =
  1761. assert t != nil
  1762. if conf.exc != excCpp:
  1763. return false
  1764. let base = t.skipTypes({tyAlias, tyPtr, tyDistinct, tyGenericInst})
  1765. if base.sym != nil and {sfCompileToCpp, sfImportc} * base.sym.flags != {}:
  1766. result = true
  1767. proc isInfixAs*(n: PNode): bool =
  1768. return n.kind == nkInfix and n[0].kind == nkIdent and n[0].ident.s == "as"
  1769. proc skipColon*(n: PNode): PNode =
  1770. result = n
  1771. if n.kind == nkExprColonExpr:
  1772. result = n[1]
  1773. proc findUnresolvedStatic*(n: PNode): PNode =
  1774. # n.typ == nil: see issue #14802
  1775. if n.kind == nkSym and n.typ != nil and n.typ.kind == tyStatic and n.typ.n == nil:
  1776. return n
  1777. for son in n:
  1778. let n = son.findUnresolvedStatic
  1779. if n != nil: return n
  1780. return nil
  1781. when false:
  1782. proc containsNil*(n: PNode): bool =
  1783. # only for debugging
  1784. if n.isNil: return true
  1785. for i in 0..<n.safeLen:
  1786. if n[i].containsNil: return true
  1787. template hasDestructor*(t: PType): bool = {tfHasAsgn, tfHasOwned} * t.flags != {}
  1788. template incompleteType*(t: PType): bool =
  1789. t.sym != nil and {sfForward, sfNoForward} * t.sym.flags == {sfForward}
  1790. template typeCompleted*(s: PSym) =
  1791. incl s.flags, sfNoForward
  1792. template detailedInfo*(sym: PSym): string =
  1793. sym.name.s
  1794. proc isInlineIterator*(typ: PType): bool {.inline.} =
  1795. typ.kind == tyProc and tfIterator in typ.flags and typ.callConv != ccClosure
  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}