ast.nim 80 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133
  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. 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, 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. 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. TTypeAttachedOp* = enum ## as usual, order is important here
  855. attachedDestructor,
  856. attachedAsgn,
  857. attachedSink,
  858. attachedTrace,
  859. attachedDeepCopy
  860. TType* {.acyclic.} = object of TIdObj # \
  861. # types are identical iff they have the
  862. # same id; there may be multiple copies of a type
  863. # in memory!
  864. # Keep in sync with PackedType
  865. kind*: TTypeKind # kind of type
  866. callConv*: TCallingConvention # for procs
  867. flags*: TTypeFlags # flags of the type
  868. sons*: TTypeSeq # base types, etc.
  869. n*: PNode # node for types:
  870. # for range types a nkRange node
  871. # for record types a nkRecord node
  872. # for enum types a list of symbols
  873. # if kind == tyInt: it is an 'int literal(x)' type
  874. # for procs and tyGenericBody, it's the
  875. # formal param list
  876. # for concepts, the concept body
  877. # else: unused
  878. owner*: PSym # the 'owner' of the type
  879. sym*: PSym # types have the sym associated with them
  880. # it is used for converting types to strings
  881. size*: BiggestInt # the size of the type in bytes
  882. # -1 means that the size is unkwown
  883. align*: int16 # the type's alignment requirements
  884. paddingAtEnd*: int16 #
  885. loc*: TLoc
  886. typeInst*: PType # for generic instantiations the tyGenericInst that led to this
  887. # type.
  888. uniqueId*: ItemId # due to a design mistake, we need to keep the real ID here as it
  889. # is required by the --incremental:on mode.
  890. TPair* = object
  891. key*, val*: RootRef
  892. TPairSeq* = seq[TPair]
  893. TIdPair* = object
  894. key*: PIdObj
  895. val*: RootRef
  896. TIdPairSeq* = seq[TIdPair]
  897. TIdTable* = object # the same as table[PIdent] of PObject
  898. counter*: int
  899. data*: TIdPairSeq
  900. TIdNodePair* = object
  901. key*: PIdObj
  902. val*: PNode
  903. TIdNodePairSeq* = seq[TIdNodePair]
  904. TIdNodeTable* = object # the same as table[PIdObj] of PNode
  905. counter*: int
  906. data*: TIdNodePairSeq
  907. TNodePair* = object
  908. h*: Hash # because it is expensive to compute!
  909. key*: PNode
  910. val*: int
  911. TNodePairSeq* = seq[TNodePair]
  912. TNodeTable* = object # the same as table[PNode] of int;
  913. # nodes are compared by structure!
  914. counter*: int
  915. data*: TNodePairSeq
  916. TObjectSeq* = seq[RootRef]
  917. TObjectSet* = object
  918. counter*: int
  919. data*: TObjectSeq
  920. TImplication* = enum
  921. impUnknown, impNo, impYes
  922. template nodeId(n: PNode): int = cast[int](n)
  923. type Gconfig = object
  924. # we put comments in a side channel to avoid increasing `sizeof(TNode)`, which
  925. # reduces memory usage given that `PNode` is the most allocated type by far.
  926. comments: Table[int, string] # nodeId => comment
  927. useIc*: bool
  928. var gconfig {.threadvar.}: Gconfig
  929. proc setUseIc*(useIc: bool) = gconfig.useIc = useIc
  930. proc comment*(n: PNode): string =
  931. if nfHasComment in n.flags and not gconfig.useIc:
  932. # IC doesn't track comments, see `packed_ast`, so this could fail
  933. result = gconfig.comments[n.nodeId]
  934. proc `comment=`*(n: PNode, a: string) =
  935. let id = n.nodeId
  936. if a.len > 0:
  937. # if needed, we could periodically cleanup gconfig.comments when its size increases,
  938. # to ensure only live nodes (and with nfHasComment) have an entry in gconfig.comments;
  939. # for compiling compiler, the waste is very small:
  940. # num calls to newNodeImpl: 14984160 (num of PNode allocations)
  941. # size of gconfig.comments: 33585
  942. # num of nodes with comments that were deleted and hence wasted: 3081
  943. n.flags.incl nfHasComment
  944. gconfig.comments[id] = a
  945. elif nfHasComment in n.flags:
  946. n.flags.excl nfHasComment
  947. gconfig.comments.del(id)
  948. # BUGFIX: a module is overloadable so that a proc can have the
  949. # same name as an imported module. This is necessary because of
  950. # the poor naming choices in the standard library.
  951. const
  952. OverloadableSyms* = {skProc, skFunc, skMethod, skIterator,
  953. skConverter, skModule, skTemplate, skMacro, skEnumField}
  954. GenericTypes*: TTypeKinds = {tyGenericInvocation, tyGenericBody,
  955. tyGenericParam}
  956. StructuralEquivTypes*: TTypeKinds = {tyNil, tyTuple, tyArray,
  957. tySet, tyRange, tyPtr, tyRef, tyVar, tyLent, tySequence, tyProc, tyOpenArray,
  958. tyVarargs}
  959. ConcreteTypes*: TTypeKinds = { # types of the expr that may occur in::
  960. # var x = expr
  961. tyBool, tyChar, tyEnum, tyArray, tyObject,
  962. tySet, tyTuple, tyRange, tyPtr, tyRef, tyVar, tyLent, tySequence, tyProc,
  963. tyPointer,
  964. tyOpenArray, tyString, tyCstring, tyInt..tyInt64, tyFloat..tyFloat128,
  965. tyUInt..tyUInt64}
  966. IntegralTypes* = {tyBool, tyChar, tyEnum, tyInt..tyInt64,
  967. tyFloat..tyFloat128, tyUInt..tyUInt64} # weird name because it contains tyFloat
  968. ConstantDataTypes*: TTypeKinds = {tyArray, tySet,
  969. tyTuple, tySequence}
  970. NilableTypes*: TTypeKinds = {tyPointer, tyCstring, tyRef, tyPtr,
  971. tyProc, tyError} # TODO
  972. PtrLikeKinds*: TTypeKinds = {tyPointer, tyPtr} # for VM
  973. PersistentNodeFlags*: TNodeFlags = {nfBase2, nfBase8, nfBase16,
  974. nfDotSetter, nfDotField,
  975. nfIsRef, nfIsPtr, nfPreventCg, nfLL,
  976. nfFromTemplate, nfDefaultRefsParam,
  977. nfExecuteOnReload, nfLastRead,
  978. nfFirstWrite, nfUseDefaultField}
  979. namePos* = 0
  980. patternPos* = 1 # empty except for term rewriting macros
  981. genericParamsPos* = 2
  982. paramsPos* = 3
  983. pragmasPos* = 4
  984. miscPos* = 5 # used for undocumented and hacky stuff
  985. bodyPos* = 6 # position of body; use rodread.getBody() instead!
  986. resultPos* = 7
  987. dispatcherPos* = 8
  988. nfAllFieldsSet* = nfBase2
  989. nkCallKinds* = {nkCall, nkInfix, nkPrefix, nkPostfix,
  990. nkCommand, nkCallStrLit, nkHiddenCallConv}
  991. nkIdentKinds* = {nkIdent, nkSym, nkAccQuoted, nkOpenSymChoice,
  992. nkClosedSymChoice}
  993. nkPragmaCallKinds* = {nkExprColonExpr, nkCall, nkCallStrLit}
  994. nkLiterals* = {nkCharLit..nkTripleStrLit}
  995. nkFloatLiterals* = {nkFloatLit..nkFloat128Lit}
  996. nkLambdaKinds* = {nkLambda, nkDo}
  997. declarativeDefs* = {nkProcDef, nkFuncDef, nkMethodDef, nkIteratorDef, nkConverterDef}
  998. routineDefs* = declarativeDefs + {nkMacroDef, nkTemplateDef}
  999. procDefs* = nkLambdaKinds + declarativeDefs
  1000. callableDefs* = nkLambdaKinds + routineDefs
  1001. nkSymChoices* = {nkClosedSymChoice, nkOpenSymChoice}
  1002. nkStrKinds* = {nkStrLit..nkTripleStrLit}
  1003. skLocalVars* = {skVar, skLet, skForVar, skParam, skResult}
  1004. skProcKinds* = {skProc, skFunc, skTemplate, skMacro, skIterator,
  1005. skMethod, skConverter}
  1006. defaultSize = -1
  1007. defaultAlignment = -1
  1008. defaultOffset* = -1
  1009. proc getPIdent*(a: PNode): PIdent {.inline.} =
  1010. ## Returns underlying `PIdent` for `{nkSym, nkIdent}`, or `nil`.
  1011. # xxx consider whether also returning the 1st ident for {nkOpenSymChoice, nkClosedSymChoice}
  1012. # which may simplify code.
  1013. case a.kind
  1014. of nkSym: a.sym.name
  1015. of nkIdent: a.ident
  1016. else: nil
  1017. const
  1018. moduleShift = when defined(cpu32): 20 else: 24
  1019. template id*(a: PIdObj): int =
  1020. let x = a
  1021. (x.itemId.module.int shl moduleShift) + x.itemId.item.int
  1022. type
  1023. IdGenerator* = ref object # unfortunately, we really need the 'shared mutable' aspect here.
  1024. module*: int32
  1025. symId*: int32
  1026. typeId*: int32
  1027. sealed*: bool
  1028. const
  1029. PackageModuleId* = -3'i32
  1030. proc idGeneratorFromModule*(m: PSym): IdGenerator =
  1031. assert m.kind == skModule
  1032. result = IdGenerator(module: m.itemId.module, symId: m.itemId.item, typeId: 0)
  1033. proc nextSymId*(x: IdGenerator): ItemId {.inline.} =
  1034. assert(not x.sealed)
  1035. inc x.symId
  1036. result = ItemId(module: x.module, item: x.symId)
  1037. proc nextTypeId*(x: IdGenerator): ItemId {.inline.} =
  1038. assert(not x.sealed)
  1039. inc x.typeId
  1040. result = ItemId(module: x.module, item: x.typeId)
  1041. when false:
  1042. proc nextId*(x: IdGenerator): ItemId {.inline.} =
  1043. inc x.item
  1044. result = x[]
  1045. when false:
  1046. proc storeBack*(dest: var IdGenerator; src: IdGenerator) {.inline.} =
  1047. assert dest.ItemId.module == src.ItemId.module
  1048. if dest.ItemId.item > src.ItemId.item:
  1049. echo dest.ItemId.item, " ", src.ItemId.item, " ", src.ItemId.module
  1050. assert dest.ItemId.item <= src.ItemId.item
  1051. dest = src
  1052. var ggDebug* {.deprecated.}: bool ## convenience switch for trying out things
  1053. proc isCallExpr*(n: PNode): bool =
  1054. result = n.kind in nkCallKinds
  1055. proc discardSons*(father: PNode)
  1056. type Indexable = PNode | PType
  1057. proc len*(n: Indexable): int {.inline.} =
  1058. result = n.sons.len
  1059. proc safeLen*(n: PNode): int {.inline.} =
  1060. ## works even for leaves.
  1061. if n.kind in {nkNone..nkNilLit}: result = 0
  1062. else: result = n.len
  1063. proc safeArrLen*(n: PNode): int {.inline.} =
  1064. ## works for array-like objects (strings passed as openArray in VM).
  1065. if n.kind in {nkStrLit..nkTripleStrLit}: result = n.strVal.len
  1066. elif n.kind in {nkNone..nkFloat128Lit}: result = 0
  1067. else: result = n.len
  1068. proc add*(father, son: Indexable) =
  1069. assert son != nil
  1070. father.sons.add(son)
  1071. proc addAllowNil*(father, son: Indexable) {.inline.} =
  1072. father.sons.add(son)
  1073. template `[]`*(n: Indexable, i: int): Indexable = n.sons[i]
  1074. template `[]=`*(n: Indexable, i: int; x: Indexable) = n.sons[i] = x
  1075. template `[]`*(n: Indexable, i: BackwardsIndex): Indexable = n[n.len - i.int]
  1076. template `[]=`*(n: Indexable, i: BackwardsIndex; x: Indexable) = n[n.len - i.int] = x
  1077. proc getDeclPragma*(n: PNode): PNode =
  1078. ## return the `nkPragma` node for declaration `n`, or `nil` if no pragma was found.
  1079. ## Currently only supports routineDefs + {nkTypeDef}.
  1080. case n.kind
  1081. of routineDefs:
  1082. if n[pragmasPos].kind != nkEmpty: result = n[pragmasPos]
  1083. of nkTypeDef:
  1084. #[
  1085. type F3*{.deprecated: "x3".} = int
  1086. TypeSection
  1087. TypeDef
  1088. PragmaExpr
  1089. Postfix
  1090. Ident "*"
  1091. Ident "F3"
  1092. Pragma
  1093. ExprColonExpr
  1094. Ident "deprecated"
  1095. StrLit "x3"
  1096. Empty
  1097. Ident "int"
  1098. ]#
  1099. if n[0].kind == nkPragmaExpr:
  1100. result = n[0][1]
  1101. else:
  1102. # support as needed for `nkIdentDefs` etc.
  1103. result = nil
  1104. if result != nil:
  1105. assert result.kind == nkPragma, $(result.kind, n.kind)
  1106. proc extractPragma*(s: PSym): PNode =
  1107. ## gets the pragma node of routine/type/var/let/const symbol `s`
  1108. if s.kind in routineKinds:
  1109. result = s.ast[pragmasPos]
  1110. elif s.kind in {skType, skVar, skLet, skConst}:
  1111. if s.ast != nil and s.ast.len > 0:
  1112. if s.ast[0].kind == nkPragmaExpr and s.ast[0].len > 1:
  1113. # s.ast = nkTypedef / nkPragmaExpr / [nkSym, nkPragma]
  1114. result = s.ast[0][1]
  1115. assert result == nil or result.kind == nkPragma
  1116. proc skipPragmaExpr*(n: PNode): PNode =
  1117. ## if pragma expr, give the node the pragmas are applied to,
  1118. ## otherwise give node itself
  1119. if n.kind == nkPragmaExpr:
  1120. result = n[0]
  1121. else:
  1122. result = n
  1123. proc setInfoRecursive*(n: PNode, info: TLineInfo) =
  1124. ## set line info recursively
  1125. if n != nil:
  1126. for i in 0..<n.safeLen: setInfoRecursive(n[i], info)
  1127. n.info = info
  1128. when defined(useNodeIds):
  1129. const nodeIdToDebug* = -1 # 2322968
  1130. var gNodeId: int
  1131. template newNodeImpl(info2) =
  1132. result = PNode(kind: kind, info: info2)
  1133. when false:
  1134. # this would add overhead, so we skip it; it results in a small amount of leaked entries
  1135. # for old PNode that gets re-allocated at the same address as a PNode that
  1136. # has `nfHasComment` set (and an entry in that table). Only `nfHasComment`
  1137. # should be used to test whether a PNode has a comment; gconfig.comments
  1138. # can contain extra entries for deleted PNode's with comments.
  1139. gconfig.comments.del(cast[int](result))
  1140. template setIdMaybe() =
  1141. when defined(useNodeIds):
  1142. result.id = gNodeId
  1143. if result.id == nodeIdToDebug:
  1144. echo "KIND ", result.kind
  1145. writeStackTrace()
  1146. inc gNodeId
  1147. proc newNode*(kind: TNodeKind): PNode =
  1148. ## new node with unknown line info, no type, and no children
  1149. newNodeImpl(unknownLineInfo)
  1150. setIdMaybe()
  1151. proc newNodeI*(kind: TNodeKind, info: TLineInfo): PNode =
  1152. ## new node with line info, no type, and no children
  1153. newNodeImpl(info)
  1154. setIdMaybe()
  1155. proc newNodeI*(kind: TNodeKind, info: TLineInfo, children: int): PNode =
  1156. ## new node with line info, type, and children
  1157. newNodeImpl(info)
  1158. if children > 0:
  1159. newSeq(result.sons, children)
  1160. setIdMaybe()
  1161. proc newNodeIT*(kind: TNodeKind, info: TLineInfo, typ: PType): PNode =
  1162. ## new node with line info, type, and no children
  1163. result = newNode(kind)
  1164. result.info = info
  1165. result.typ = typ
  1166. proc newTree*(kind: TNodeKind; children: varargs[PNode]): PNode =
  1167. result = newNode(kind)
  1168. if children.len > 0:
  1169. result.info = children[0].info
  1170. result.sons = @children
  1171. proc newTreeI*(kind: TNodeKind; info: TLineInfo; children: varargs[PNode]): PNode =
  1172. result = newNodeI(kind, info)
  1173. if children.len > 0:
  1174. result.info = children[0].info
  1175. result.sons = @children
  1176. proc newTreeIT*(kind: TNodeKind; info: TLineInfo; typ: PType; children: varargs[PNode]): PNode =
  1177. result = newNodeIT(kind, info, typ)
  1178. if children.len > 0:
  1179. result.info = children[0].info
  1180. result.sons = @children
  1181. template previouslyInferred*(t: PType): PType =
  1182. if t.sons.len > 1: t.lastSon else: nil
  1183. when false:
  1184. import tables, strutils
  1185. var x: CountTable[string]
  1186. addQuitProc proc () {.noconv.} =
  1187. for k, v in pairs(x):
  1188. echo k
  1189. echo v
  1190. proc newSym*(symKind: TSymKind, name: PIdent, id: ItemId, owner: PSym,
  1191. info: TLineInfo; options: TOptions = {}): PSym =
  1192. # generates a symbol and initializes the hash field too
  1193. result = PSym(name: name, kind: symKind, flags: {}, info: info, itemId: id,
  1194. options: options, owner: owner, offset: defaultOffset)
  1195. when false:
  1196. if id.module == 48 and id.item == 39:
  1197. writeStackTrace()
  1198. echo "kind ", symKind, " ", name.s
  1199. if owner != nil: echo owner.name.s
  1200. proc astdef*(s: PSym): PNode =
  1201. # get only the definition (initializer) portion of the ast
  1202. if s.ast != nil and s.ast.kind in {nkIdentDefs, nkConstDef}:
  1203. s.ast[2]
  1204. else:
  1205. s.ast
  1206. proc isMetaType*(t: PType): bool =
  1207. return t.kind in tyMetaTypes or
  1208. (t.kind == tyStatic and t.n == nil) or
  1209. tfHasMeta in t.flags
  1210. proc isUnresolvedStatic*(t: PType): bool =
  1211. return t.kind == tyStatic and t.n == nil
  1212. proc linkTo*(t: PType, s: PSym): PType {.discardable.} =
  1213. t.sym = s
  1214. s.typ = t
  1215. result = t
  1216. proc linkTo*(s: PSym, t: PType): PSym {.discardable.} =
  1217. t.sym = s
  1218. s.typ = t
  1219. result = s
  1220. template fileIdx*(c: PSym): FileIndex =
  1221. # XXX: this should be used only on module symbols
  1222. c.position.FileIndex
  1223. template filename*(c: PSym): string =
  1224. # XXX: this should be used only on module symbols
  1225. c.position.FileIndex.toFilename
  1226. proc appendToModule*(m: PSym, n: PNode) =
  1227. ## The compiler will use this internally to add nodes that will be
  1228. ## appended to the module after the sem pass
  1229. if m.ast == nil:
  1230. m.ast = newNode(nkStmtList)
  1231. m.ast.sons = @[n]
  1232. else:
  1233. assert m.ast.kind == nkStmtList
  1234. m.ast.sons.add(n)
  1235. const # for all kind of hash tables:
  1236. GrowthFactor* = 2 # must be power of 2, > 0
  1237. StartSize* = 8 # must be power of 2, > 0
  1238. proc copyStrTable*(dest: var TStrTable, src: TStrTable) =
  1239. dest.counter = src.counter
  1240. setLen(dest.data, src.data.len)
  1241. for i in 0..high(src.data): dest.data[i] = src.data[i]
  1242. proc copyIdTable*(dest: var TIdTable, src: TIdTable) =
  1243. dest.counter = src.counter
  1244. newSeq(dest.data, src.data.len)
  1245. for i in 0..high(src.data): dest.data[i] = src.data[i]
  1246. proc copyObjectSet*(dest: var TObjectSet, src: TObjectSet) =
  1247. dest.counter = src.counter
  1248. setLen(dest.data, src.data.len)
  1249. for i in 0..high(src.data): dest.data[i] = src.data[i]
  1250. proc discardSons*(father: PNode) =
  1251. father.sons = @[]
  1252. proc withInfo*(n: PNode, info: TLineInfo): PNode =
  1253. n.info = info
  1254. return n
  1255. proc newIdentNode*(ident: PIdent, info: TLineInfo): PNode =
  1256. result = newNode(nkIdent)
  1257. result.ident = ident
  1258. result.info = info
  1259. proc newSymNode*(sym: PSym): PNode =
  1260. result = newNode(nkSym)
  1261. result.sym = sym
  1262. result.typ = sym.typ
  1263. result.info = sym.info
  1264. proc newSymNode*(sym: PSym, info: TLineInfo): PNode =
  1265. result = newNode(nkSym)
  1266. result.sym = sym
  1267. result.typ = sym.typ
  1268. result.info = info
  1269. proc newIntNode*(kind: TNodeKind, intVal: BiggestInt): PNode =
  1270. result = newNode(kind)
  1271. result.intVal = intVal
  1272. proc newIntNode*(kind: TNodeKind, intVal: Int128): PNode =
  1273. result = newNode(kind)
  1274. result.intVal = castToInt64(intVal)
  1275. proc lastSon*(n: Indexable): Indexable = n.sons[^1]
  1276. proc skipTypes*(t: PType, kinds: TTypeKinds): PType =
  1277. ## Used throughout the compiler code to test whether a type tree contains or
  1278. ## doesn't contain a specific type/types - it is often the case that only the
  1279. ## last child nodes of a type tree need to be searched. This is a really hot
  1280. ## path within the compiler!
  1281. result = t
  1282. while result.kind in kinds: result = lastSon(result)
  1283. proc newIntTypeNode*(intVal: BiggestInt, typ: PType): PNode =
  1284. let kind = skipTypes(typ, abstractVarRange).kind
  1285. case kind
  1286. of tyInt: result = newNode(nkIntLit)
  1287. of tyInt8: result = newNode(nkInt8Lit)
  1288. of tyInt16: result = newNode(nkInt16Lit)
  1289. of tyInt32: result = newNode(nkInt32Lit)
  1290. of tyInt64: result = newNode(nkInt64Lit)
  1291. of tyChar: result = newNode(nkCharLit)
  1292. of tyUInt: result = newNode(nkUIntLit)
  1293. of tyUInt8: result = newNode(nkUInt8Lit)
  1294. of tyUInt16: result = newNode(nkUInt16Lit)
  1295. of tyUInt32: result = newNode(nkUInt32Lit)
  1296. of tyUInt64: result = newNode(nkUInt64Lit)
  1297. of tyBool, tyEnum:
  1298. # XXX: does this really need to be the kind nkIntLit?
  1299. result = newNode(nkIntLit)
  1300. of tyStatic: # that's a pre-existing bug, will fix in another PR
  1301. result = newNode(nkIntLit)
  1302. else: doAssert false, $kind
  1303. result.intVal = intVal
  1304. result.typ = typ
  1305. proc newIntTypeNode*(intVal: Int128, typ: PType): PNode =
  1306. # XXX: introduce range check
  1307. newIntTypeNode(castToInt64(intVal), typ)
  1308. proc newFloatNode*(kind: TNodeKind, floatVal: BiggestFloat): PNode =
  1309. result = newNode(kind)
  1310. result.floatVal = floatVal
  1311. proc newStrNode*(kind: TNodeKind, strVal: string): PNode =
  1312. result = newNode(kind)
  1313. result.strVal = strVal
  1314. proc newStrNode*(strVal: string; info: TLineInfo): PNode =
  1315. result = newNodeI(nkStrLit, info)
  1316. result.strVal = strVal
  1317. proc newProcNode*(kind: TNodeKind, info: TLineInfo, body: PNode,
  1318. params,
  1319. name, pattern, genericParams,
  1320. pragmas, exceptions: PNode): PNode =
  1321. result = newNodeI(kind, info)
  1322. result.sons = @[name, pattern, genericParams, params,
  1323. pragmas, exceptions, body]
  1324. const
  1325. AttachedOpToStr*: array[TTypeAttachedOp, string] = [
  1326. "=destroy", "=copy", "=sink", "=trace", "=deepcopy"]
  1327. proc `$`*(s: PSym): string =
  1328. if s != nil:
  1329. result = s.name.s & "@" & $s.id
  1330. else:
  1331. result = "<nil>"
  1332. proc newType*(kind: TTypeKind, id: ItemId; owner: PSym): PType =
  1333. result = PType(kind: kind, owner: owner, size: defaultSize,
  1334. align: defaultAlignment, itemId: id,
  1335. uniqueId: id)
  1336. when false:
  1337. if result.itemId.module == 55 and result.itemId.item == 2:
  1338. echo "KNID ", kind
  1339. writeStackTrace()
  1340. proc mergeLoc(a: var TLoc, b: TLoc) =
  1341. if a.k == low(typeof(a.k)): a.k = b.k
  1342. if a.storage == low(typeof(a.storage)): a.storage = b.storage
  1343. a.flags.incl b.flags
  1344. if a.lode == nil: a.lode = b.lode
  1345. if a.r == "": a.r = b.r
  1346. proc newSons*(father: Indexable, length: int) =
  1347. setLen(father.sons, length)
  1348. proc assignType*(dest, src: PType) =
  1349. dest.kind = src.kind
  1350. dest.flags = src.flags
  1351. dest.callConv = src.callConv
  1352. dest.n = src.n
  1353. dest.size = src.size
  1354. dest.align = src.align
  1355. # this fixes 'type TLock = TSysLock':
  1356. if src.sym != nil:
  1357. if dest.sym != nil:
  1358. dest.sym.flags.incl src.sym.flags-{sfUsed, sfExported}
  1359. if dest.sym.annex == nil: dest.sym.annex = src.sym.annex
  1360. mergeLoc(dest.sym.loc, src.sym.loc)
  1361. else:
  1362. dest.sym = src.sym
  1363. newSons(dest, src.len)
  1364. for i in 0..<src.len: dest[i] = src[i]
  1365. proc copyType*(t: PType, id: ItemId, owner: PSym): PType =
  1366. result = newType(t.kind, id, owner)
  1367. assignType(result, t)
  1368. result.sym = t.sym # backend-info should not be copied
  1369. proc exactReplica*(t: PType): PType =
  1370. result = copyType(t, t.itemId, t.owner)
  1371. proc copySym*(s: PSym; id: ItemId): PSym =
  1372. result = newSym(s.kind, s.name, id, s.owner, s.info, s.options)
  1373. #result.ast = nil # BUGFIX; was: s.ast which made problems
  1374. result.typ = s.typ
  1375. result.flags = s.flags
  1376. result.magic = s.magic
  1377. result.options = s.options
  1378. result.position = s.position
  1379. result.loc = s.loc
  1380. result.annex = s.annex # BUGFIX
  1381. result.constraint = s.constraint
  1382. if result.kind in {skVar, skLet, skField}:
  1383. result.guard = s.guard
  1384. result.bitsize = s.bitsize
  1385. result.alignment = s.alignment
  1386. proc createModuleAlias*(s: PSym, id: ItemId, newIdent: PIdent, info: TLineInfo;
  1387. options: TOptions): PSym =
  1388. result = newSym(s.kind, newIdent, id, s.owner, info, options)
  1389. # keep ID!
  1390. result.ast = s.ast
  1391. #result.id = s.id # XXX figure out what to do with the ID.
  1392. result.flags = s.flags
  1393. result.options = s.options
  1394. result.position = s.position
  1395. result.loc = s.loc
  1396. result.annex = s.annex
  1397. proc initStrTable*(x: var TStrTable) =
  1398. x.counter = 0
  1399. newSeq(x.data, StartSize)
  1400. proc newStrTable*: TStrTable =
  1401. initStrTable(result)
  1402. proc initIdTable*(x: var TIdTable) =
  1403. x.counter = 0
  1404. newSeq(x.data, StartSize)
  1405. proc newIdTable*: TIdTable =
  1406. initIdTable(result)
  1407. proc resetIdTable*(x: var TIdTable) =
  1408. x.counter = 0
  1409. # clear and set to old initial size:
  1410. setLen(x.data, 0)
  1411. setLen(x.data, StartSize)
  1412. proc initObjectSet*(x: var TObjectSet) =
  1413. x.counter = 0
  1414. newSeq(x.data, StartSize)
  1415. proc initIdNodeTable*(x: var TIdNodeTable) =
  1416. x.counter = 0
  1417. newSeq(x.data, StartSize)
  1418. proc initNodeTable*(x: var TNodeTable) =
  1419. x.counter = 0
  1420. newSeq(x.data, StartSize)
  1421. proc skipTypes*(t: PType, kinds: TTypeKinds; maxIters: int): PType =
  1422. result = t
  1423. var i = maxIters
  1424. while result.kind in kinds:
  1425. result = lastSon(result)
  1426. dec i
  1427. if i == 0: return nil
  1428. proc skipTypesOrNil*(t: PType, kinds: TTypeKinds): PType =
  1429. ## same as skipTypes but handles 'nil'
  1430. result = t
  1431. while result != nil and result.kind in kinds:
  1432. if result.len == 0: return nil
  1433. result = lastSon(result)
  1434. proc isGCedMem*(t: PType): bool {.inline.} =
  1435. result = t.kind in {tyString, tyRef, tySequence} or
  1436. t.kind == tyProc and t.callConv == ccClosure
  1437. proc propagateToOwner*(owner, elem: PType; propagateHasAsgn = true) =
  1438. owner.flags.incl elem.flags * {tfHasMeta, tfTriggersCompileTime}
  1439. if tfNotNil in elem.flags:
  1440. if owner.kind in {tyGenericInst, tyGenericBody, tyGenericInvocation}:
  1441. owner.flags.incl tfNotNil
  1442. if elem.isMetaType:
  1443. owner.flags.incl tfHasMeta
  1444. let mask = elem.flags * {tfHasAsgn, tfHasOwned}
  1445. if mask != {} and propagateHasAsgn:
  1446. let o2 = owner.skipTypes({tyGenericInst, tyAlias, tySink})
  1447. if o2.kind in {tyTuple, tyObject, tyArray,
  1448. tySequence, tySet, tyDistinct}:
  1449. o2.flags.incl mask
  1450. owner.flags.incl mask
  1451. if owner.kind notin {tyProc, tyGenericInst, tyGenericBody,
  1452. tyGenericInvocation, tyPtr}:
  1453. let elemB = elem.skipTypes({tyGenericInst, tyAlias, tySink})
  1454. if elemB.isGCedMem or tfHasGCedMem in elemB.flags:
  1455. # for simplicity, we propagate this flag even to generics. We then
  1456. # ensure this doesn't bite us in sempass2.
  1457. owner.flags.incl tfHasGCedMem
  1458. proc rawAddSon*(father, son: PType; propagateHasAsgn = true) =
  1459. father.sons.add(son)
  1460. if not son.isNil: propagateToOwner(father, son, propagateHasAsgn)
  1461. proc rawAddSonNoPropagationOfTypeFlags*(father, son: PType) =
  1462. father.sons.add(son)
  1463. proc addSonNilAllowed*(father, son: PNode) =
  1464. father.sons.add(son)
  1465. proc delSon*(father: PNode, idx: int) =
  1466. if father.len == 0: return
  1467. for i in idx..<father.len - 1: father[i] = father[i + 1]
  1468. father.sons.setLen(father.len - 1)
  1469. proc copyNode*(src: PNode): PNode =
  1470. # does not copy its sons!
  1471. if src == nil:
  1472. return nil
  1473. result = newNode(src.kind)
  1474. result.info = src.info
  1475. result.typ = src.typ
  1476. result.flags = src.flags * PersistentNodeFlags
  1477. result.comment = src.comment
  1478. when defined(useNodeIds):
  1479. if result.id == nodeIdToDebug:
  1480. echo "COMES FROM ", src.id
  1481. case src.kind
  1482. of nkCharLit..nkUInt64Lit: result.intVal = src.intVal
  1483. of nkFloatLiterals: result.floatVal = src.floatVal
  1484. of nkSym: result.sym = src.sym
  1485. of nkIdent: result.ident = src.ident
  1486. of nkStrLit..nkTripleStrLit: result.strVal = src.strVal
  1487. else: discard
  1488. template transitionNodeKindCommon(k: TNodeKind) =
  1489. let obj {.inject.} = n[]
  1490. n[] = TNode(kind: k, typ: obj.typ, info: obj.info, flags: obj.flags)
  1491. # n.comment = obj.comment # shouldn't be needed, the address doesnt' change
  1492. when defined(useNodeIds):
  1493. n.id = obj.id
  1494. proc transitionSonsKind*(n: PNode, kind: range[nkComesFrom..nkTupleConstr]) =
  1495. transitionNodeKindCommon(kind)
  1496. n.sons = obj.sons
  1497. proc transitionIntKind*(n: PNode, kind: range[nkCharLit..nkUInt64Lit]) =
  1498. transitionNodeKindCommon(kind)
  1499. n.intVal = obj.intVal
  1500. proc transitionIntToFloatKind*(n: PNode, kind: range[nkFloatLit..nkFloat128Lit]) =
  1501. transitionNodeKindCommon(kind)
  1502. n.floatVal = BiggestFloat(obj.intVal)
  1503. proc transitionNoneToSym*(n: PNode) =
  1504. transitionNodeKindCommon(nkSym)
  1505. template transitionSymKindCommon*(k: TSymKind) =
  1506. let obj {.inject.} = s[]
  1507. s[] = TSym(kind: k, itemId: obj.itemId, magic: obj.magic, typ: obj.typ, name: obj.name,
  1508. info: obj.info, owner: obj.owner, flags: obj.flags, ast: obj.ast,
  1509. options: obj.options, position: obj.position, offset: obj.offset,
  1510. loc: obj.loc, annex: obj.annex, constraint: obj.constraint)
  1511. when hasFFI:
  1512. s.cname = obj.cname
  1513. when defined(nimsuggest):
  1514. s.allUsages = obj.allUsages
  1515. proc transitionGenericParamToType*(s: PSym) =
  1516. transitionSymKindCommon(skType)
  1517. proc transitionRoutineSymKind*(s: PSym, kind: range[skProc..skTemplate]) =
  1518. transitionSymKindCommon(kind)
  1519. s.gcUnsafetyReason = obj.gcUnsafetyReason
  1520. s.transformedBody = obj.transformedBody
  1521. proc transitionToLet*(s: PSym) =
  1522. transitionSymKindCommon(skLet)
  1523. s.guard = obj.guard
  1524. s.bitsize = obj.bitsize
  1525. s.alignment = obj.alignment
  1526. template copyNodeImpl(dst, src, processSonsStmt) =
  1527. if src == nil: return
  1528. dst = newNode(src.kind)
  1529. dst.info = src.info
  1530. dst.typ = src.typ
  1531. dst.flags = src.flags * PersistentNodeFlags
  1532. dst.comment = src.comment
  1533. when defined(useNodeIds):
  1534. if dst.id == nodeIdToDebug:
  1535. echo "COMES FROM ", src.id
  1536. case src.kind
  1537. of nkCharLit..nkUInt64Lit: dst.intVal = src.intVal
  1538. of nkFloatLiterals: dst.floatVal = src.floatVal
  1539. of nkSym: dst.sym = src.sym
  1540. of nkIdent: dst.ident = src.ident
  1541. of nkStrLit..nkTripleStrLit: dst.strVal = src.strVal
  1542. else: processSonsStmt
  1543. proc shallowCopy*(src: PNode): PNode =
  1544. # does not copy its sons, but provides space for them:
  1545. copyNodeImpl(result, src):
  1546. newSeq(result.sons, src.len)
  1547. proc copyTree*(src: PNode): PNode =
  1548. # copy a whole syntax tree; performs deep copying
  1549. copyNodeImpl(result, src):
  1550. newSeq(result.sons, src.len)
  1551. for i in 0..<src.len:
  1552. result[i] = copyTree(src[i])
  1553. proc copyTreeWithoutNode*(src, skippedNode: PNode): PNode =
  1554. copyNodeImpl(result, src):
  1555. result.sons = newSeqOfCap[PNode](src.len)
  1556. for n in src.sons:
  1557. if n != skippedNode:
  1558. result.sons.add copyTreeWithoutNode(n, skippedNode)
  1559. proc hasSonWith*(n: PNode, kind: TNodeKind): bool =
  1560. for i in 0..<n.len:
  1561. if n[i].kind == kind:
  1562. return true
  1563. result = false
  1564. proc hasNilSon*(n: PNode): bool =
  1565. for i in 0..<n.safeLen:
  1566. if n[i] == nil:
  1567. return true
  1568. elif hasNilSon(n[i]):
  1569. return true
  1570. result = false
  1571. proc containsNode*(n: PNode, kinds: TNodeKinds): bool =
  1572. if n == nil: return
  1573. case n.kind
  1574. of nkEmpty..nkNilLit: result = n.kind in kinds
  1575. else:
  1576. for i in 0..<n.len:
  1577. if n.kind in kinds or containsNode(n[i], kinds): return true
  1578. proc hasSubnodeWith*(n: PNode, kind: TNodeKind): bool =
  1579. case n.kind
  1580. of nkEmpty..nkNilLit, nkFormalParams: result = n.kind == kind
  1581. else:
  1582. for i in 0..<n.len:
  1583. if (n[i].kind == kind) or hasSubnodeWith(n[i], kind):
  1584. return true
  1585. result = false
  1586. proc getInt*(a: PNode): Int128 =
  1587. case a.kind
  1588. of nkCharLit, nkUIntLit..nkUInt64Lit:
  1589. result = toInt128(cast[uint64](a.intVal))
  1590. of nkInt8Lit..nkInt64Lit:
  1591. result = toInt128(a.intVal)
  1592. of nkIntLit:
  1593. # XXX: enable this assert
  1594. # assert a.typ.kind notin {tyChar, tyUint..tyUInt64}
  1595. result = toInt128(a.intVal)
  1596. else:
  1597. raiseRecoverableError("cannot extract number from invalid AST node")
  1598. proc getInt64*(a: PNode): int64 {.deprecated: "use getInt".} =
  1599. case a.kind
  1600. of nkCharLit, nkUIntLit..nkUInt64Lit, nkIntLit..nkInt64Lit:
  1601. result = a.intVal
  1602. else:
  1603. raiseRecoverableError("cannot extract number from invalid AST node")
  1604. proc getFloat*(a: PNode): BiggestFloat =
  1605. case a.kind
  1606. of nkFloatLiterals: result = a.floatVal
  1607. of nkCharLit, nkUIntLit..nkUInt64Lit, nkIntLit..nkInt64Lit:
  1608. result = BiggestFloat a.intVal
  1609. else:
  1610. raiseRecoverableError("cannot extract number from invalid AST node")
  1611. #doAssert false, "getFloat"
  1612. #internalError(a.info, "getFloat")
  1613. #result = 0.0
  1614. proc getStr*(a: PNode): string =
  1615. case a.kind
  1616. of nkStrLit..nkTripleStrLit: result = a.strVal
  1617. of nkNilLit:
  1618. # let's hope this fixes more problems than it creates:
  1619. result = ""
  1620. else:
  1621. raiseRecoverableError("cannot extract string from invalid AST node")
  1622. #doAssert false, "getStr"
  1623. #internalError(a.info, "getStr")
  1624. #result = ""
  1625. proc getStrOrChar*(a: PNode): string =
  1626. case a.kind
  1627. of nkStrLit..nkTripleStrLit: result = a.strVal
  1628. of nkCharLit..nkUInt64Lit: result = $chr(int(a.intVal))
  1629. else:
  1630. raiseRecoverableError("cannot extract string from invalid AST node")
  1631. #doAssert false, "getStrOrChar"
  1632. #internalError(a.info, "getStrOrChar")
  1633. #result = ""
  1634. proc isGenericParams*(n: PNode): bool {.inline.} =
  1635. ## used to judge whether a node is generic params.
  1636. n != nil and n.kind == nkGenericParams
  1637. proc isGenericRoutine*(n: PNode): bool {.inline.} =
  1638. n != nil and n.kind in callableDefs and n[genericParamsPos].isGenericParams
  1639. proc isGenericRoutineStrict*(s: PSym): bool {.inline.} =
  1640. ## determines if this symbol represents a generic routine
  1641. ## the unusual name is so it doesn't collide and eventually replaces
  1642. ## `isGenericRoutine`
  1643. s.kind in skProcKinds and s.ast.isGenericRoutine
  1644. proc isGenericRoutine*(s: PSym): bool {.inline.} =
  1645. ## determines if this symbol represents a generic routine or an instance of
  1646. ## one. This should be renamed accordingly and `isGenericRoutineStrict`
  1647. ## should take this name instead.
  1648. ##
  1649. ## Warning/XXX: Unfortunately, it considers a proc kind symbol flagged with
  1650. ## sfFromGeneric as a generic routine. Instead this should likely not be the
  1651. ## case and the concepts should be teased apart:
  1652. ## - generic definition
  1653. ## - generic instance
  1654. ## - either generic definition or instance
  1655. s.kind in skProcKinds and (sfFromGeneric in s.flags or
  1656. s.ast.isGenericRoutine)
  1657. proc skipGenericOwner*(s: PSym): PSym =
  1658. ## Generic instantiations are owned by their originating generic
  1659. ## symbol. This proc skips such owners and goes straight to the owner
  1660. ## of the generic itself (the module or the enclosing proc).
  1661. result = if s.kind in skProcKinds and sfFromGeneric in s.flags:
  1662. s.owner.owner
  1663. else:
  1664. s.owner
  1665. proc originatingModule*(s: PSym): PSym =
  1666. result = s.owner
  1667. while result.kind != skModule: result = result.owner
  1668. proc isRoutine*(s: PSym): bool {.inline.} =
  1669. result = s.kind in skProcKinds
  1670. proc isCompileTimeProc*(s: PSym): bool {.inline.} =
  1671. result = s.kind == skMacro or
  1672. s.kind in {skProc, skFunc} and sfCompileTime in s.flags
  1673. proc isRunnableExamples*(n: PNode): bool =
  1674. # Templates and generics don't perform symbol lookups.
  1675. result = n.kind == nkSym and n.sym.magic == mRunnableExamples or
  1676. n.kind == nkIdent and n.ident.s == "runnableExamples"
  1677. proc requiredParams*(s: PSym): int =
  1678. # Returns the number of required params (without default values)
  1679. # XXX: Perhaps we can store this in the `offset` field of the
  1680. # symbol instead?
  1681. for i in 1..<s.typ.len:
  1682. if s.typ.n[i].sym.ast != nil:
  1683. return i - 1
  1684. return s.typ.len - 1
  1685. proc hasPattern*(s: PSym): bool {.inline.} =
  1686. result = isRoutine(s) and s.ast[patternPos].kind != nkEmpty
  1687. iterator items*(n: PNode): PNode =
  1688. for i in 0..<n.safeLen: yield n[i]
  1689. iterator pairs*(n: PNode): tuple[i: int, n: PNode] =
  1690. for i in 0..<n.safeLen: yield (i, n[i])
  1691. proc isAtom*(n: PNode): bool {.inline.} =
  1692. result = n.kind >= nkNone and n.kind <= nkNilLit
  1693. proc isEmptyType*(t: PType): bool {.inline.} =
  1694. ## 'void' and 'typed' types are often equivalent to 'nil' these days:
  1695. result = t == nil or t.kind in {tyVoid, tyTyped}
  1696. proc makeStmtList*(n: PNode): PNode =
  1697. if n.kind == nkStmtList:
  1698. result = n
  1699. else:
  1700. result = newNodeI(nkStmtList, n.info)
  1701. result.add n
  1702. proc skipStmtList*(n: PNode): PNode =
  1703. if n.kind in {nkStmtList, nkStmtListExpr}:
  1704. for i in 0..<n.len-1:
  1705. if n[i].kind notin {nkEmpty, nkCommentStmt}: return n
  1706. result = n.lastSon
  1707. else:
  1708. result = n
  1709. proc toVar*(typ: PType; kind: TTypeKind; idgen: IdGenerator): PType =
  1710. ## If ``typ`` is not a tyVar then it is converted into a `var <typ>` and
  1711. ## returned. Otherwise ``typ`` is simply returned as-is.
  1712. result = typ
  1713. if typ.kind != kind:
  1714. result = newType(kind, nextTypeId(idgen), typ.owner)
  1715. rawAddSon(result, typ)
  1716. proc toRef*(typ: PType; idgen: IdGenerator): PType =
  1717. ## If ``typ`` is a tyObject then it is converted into a `ref <typ>` and
  1718. ## returned. Otherwise ``typ`` is simply returned as-is.
  1719. result = typ
  1720. if typ.skipTypes({tyAlias, tyGenericInst}).kind == tyObject:
  1721. result = newType(tyRef, nextTypeId(idgen), typ.owner)
  1722. rawAddSon(result, typ)
  1723. proc toObject*(typ: PType): PType =
  1724. ## If ``typ`` is a tyRef then its immediate son is returned (which in many
  1725. ## cases should be a ``tyObject``).
  1726. ## Otherwise ``typ`` is simply returned as-is.
  1727. let t = typ.skipTypes({tyAlias, tyGenericInst})
  1728. if t.kind == tyRef: t.lastSon
  1729. else: typ
  1730. proc toObjectFromRefPtrGeneric*(typ: PType): PType =
  1731. #[
  1732. See also `toObject`.
  1733. Finds the underlying `object`, even in cases like these:
  1734. type
  1735. B[T] = object f0: int
  1736. A1[T] = ref B[T]
  1737. A2[T] = ref object f1: int
  1738. A3 = ref object f2: int
  1739. A4 = object f3: int
  1740. ]#
  1741. result = typ
  1742. while true:
  1743. case result.kind
  1744. of tyGenericBody: result = result.lastSon
  1745. of tyRef, tyPtr, tyGenericInst, tyGenericInvocation, tyAlias: result = result[0]
  1746. # automatic dereferencing is deep, refs #18298.
  1747. else: break
  1748. assert result.sym != nil
  1749. proc isImportedException*(t: PType; conf: ConfigRef): bool =
  1750. assert t != nil
  1751. if conf.exc != excCpp:
  1752. return false
  1753. let base = t.skipTypes({tyAlias, tyPtr, tyDistinct, tyGenericInst})
  1754. if base.sym != nil and {sfCompileToCpp, sfImportc} * base.sym.flags != {}:
  1755. result = true
  1756. proc isInfixAs*(n: PNode): bool =
  1757. return n.kind == nkInfix and n[0].kind == nkIdent and n[0].ident.s == "as"
  1758. proc skipColon*(n: PNode): PNode =
  1759. result = n
  1760. if n.kind == nkExprColonExpr:
  1761. result = n[1]
  1762. proc findUnresolvedStatic*(n: PNode): PNode =
  1763. # n.typ == nil: see issue #14802
  1764. if n.kind == nkSym and n.typ != nil and n.typ.kind == tyStatic and n.typ.n == nil:
  1765. return n
  1766. for son in n:
  1767. let n = son.findUnresolvedStatic
  1768. if n != nil: return n
  1769. return nil
  1770. when false:
  1771. proc containsNil*(n: PNode): bool =
  1772. # only for debugging
  1773. if n.isNil: return true
  1774. for i in 0..<n.safeLen:
  1775. if n[i].containsNil: return true
  1776. template hasDestructor*(t: PType): bool = {tfHasAsgn, tfHasOwned} * t.flags != {}
  1777. template incompleteType*(t: PType): bool =
  1778. t.sym != nil and {sfForward, sfNoForward} * t.sym.flags == {sfForward}
  1779. template typeCompleted*(s: PSym) =
  1780. incl s.flags, sfNoForward
  1781. template detailedInfo*(sym: PSym): string =
  1782. sym.name.s
  1783. proc isInlineIterator*(typ: PType): bool {.inline.} =
  1784. typ.kind == tyProc and tfIterator in typ.flags and typ.callConv != ccClosure
  1785. proc isIterator*(typ: PType): bool {.inline.} =
  1786. typ.kind == tyProc and tfIterator in typ.flags
  1787. proc isClosureIterator*(typ: PType): bool {.inline.} =
  1788. typ.kind == tyProc and tfIterator in typ.flags and typ.callConv == ccClosure
  1789. proc isClosure*(typ: PType): bool {.inline.} =
  1790. typ.kind == tyProc and typ.callConv == ccClosure
  1791. proc isSinkParam*(s: PSym): bool {.inline.} =
  1792. s.kind == skParam and (s.typ.kind == tySink or tfHasOwned in s.typ.flags)
  1793. proc isSinkType*(t: PType): bool {.inline.} =
  1794. t.kind == tySink or tfHasOwned in t.flags
  1795. proc newProcType*(info: TLineInfo; id: ItemId; owner: PSym): PType =
  1796. result = newType(tyProc, id, owner)
  1797. result.n = newNodeI(nkFormalParams, info)
  1798. rawAddSon(result, nil) # return type
  1799. # result.n[0] used to be `nkType`, but now it's `nkEffectList` because
  1800. # the effects are now stored in there too ... this is a bit hacky, but as
  1801. # usual we desperately try to save memory:
  1802. result.n.add newNodeI(nkEffectList, info)
  1803. proc addParam*(procType: PType; param: PSym) =
  1804. param.position = procType.len-1
  1805. procType.n.add newSymNode(param)
  1806. rawAddSon(procType, param.typ)
  1807. const magicsThatCanRaise = {
  1808. mNone, mSlurp, mStaticExec, mParseExprToAst, mParseStmtToAst, mEcho}
  1809. proc canRaiseConservative*(fn: PNode): bool =
  1810. if fn.kind == nkSym and fn.sym.magic notin magicsThatCanRaise:
  1811. result = false
  1812. else:
  1813. result = true
  1814. proc canRaise*(fn: PNode): bool =
  1815. if fn.kind == nkSym and (fn.sym.magic notin magicsThatCanRaise or
  1816. {sfImportc, sfInfixCall} * fn.sym.flags == {sfImportc} or
  1817. sfGeneratedOp in fn.sym.flags):
  1818. result = false
  1819. elif fn.kind == nkSym and fn.sym.magic == mEcho:
  1820. result = true
  1821. else:
  1822. # TODO check for n having sons? or just return false for now if not
  1823. if fn.typ != nil and fn.typ.n != nil and fn.typ.n[0].kind == nkSym:
  1824. result = false
  1825. else:
  1826. result = fn.typ != nil and fn.typ.n != nil and ((fn.typ.n[0].len < effectListLen) or
  1827. (fn.typ.n[0][exceptionEffects] != nil and
  1828. fn.typ.n[0][exceptionEffects].safeLen > 0))
  1829. proc toHumanStrImpl[T](kind: T, num: static int): string =
  1830. result = $kind
  1831. result = result[num..^1]
  1832. result[0] = result[0].toLowerAscii
  1833. proc toHumanStr*(kind: TSymKind): string =
  1834. ## strips leading `sk`
  1835. result = toHumanStrImpl(kind, 2)
  1836. proc toHumanStr*(kind: TTypeKind): string =
  1837. ## strips leading `tk`
  1838. result = toHumanStrImpl(kind, 2)
  1839. proc skipAddr*(n: PNode): PNode {.inline.} =
  1840. (if n.kind == nkHiddenAddr: n[0] else: n)
  1841. proc isNewStyleConcept*(n: PNode): bool {.inline.} =
  1842. assert n.kind == nkTypeClassTy
  1843. result = n[0].kind == nkEmpty
  1844. proc isOutParam*(t: PType): bool {.inline.} = tfIsOutParam in t.flags
  1845. const
  1846. nodesToIgnoreSet* = {nkNone..pred(nkSym), succ(nkSym)..nkNilLit,
  1847. nkTypeSection, nkProcDef, nkConverterDef,
  1848. nkMethodDef, nkIteratorDef, nkMacroDef, nkTemplateDef, nkLambda, nkDo,
  1849. nkFuncDef, nkConstSection, nkConstDef, nkIncludeStmt, nkImportStmt,
  1850. nkExportStmt, nkPragma, nkCommentStmt, nkBreakState,
  1851. nkTypeOfExpr, nkMixinStmt, nkBindStmt}