options.nim 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096
  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. import
  10. lineinfos, platform,
  11. prefixmatches, pathutils, nimpaths
  12. import std/[tables, os, strutils, strtabs, sets]
  13. from std/terminal import isatty
  14. from std/times import utc, fromUnix, local, getTime, format, DateTime
  15. from std/private/globs import nativeToUnixPath
  16. when defined(nimPreviewSlimSystem):
  17. import std/[syncio, assertions]
  18. const
  19. hasTinyCBackend* = defined(tinyc)
  20. useEffectSystem* = true
  21. useWriteTracking* = false
  22. hasFFI* = defined(nimHasLibFFI)
  23. copyrightYear* = "2024"
  24. nimEnableCovariance* = defined(nimEnableCovariance)
  25. type # please make sure we have under 32 options
  26. # (improves code efficiency a lot!)
  27. TOption* = enum # **keep binary compatible**
  28. optNone, optObjCheck, optFieldCheck, optRangeCheck, optBoundsCheck,
  29. optOverflowCheck, optRefCheck,
  30. optNaNCheck, optInfCheck, optStaticBoundsCheck, optStyleCheck,
  31. optAssert, optLineDir, optWarns, optHints,
  32. optOptimizeSpeed, optOptimizeSize,
  33. optStackTrace, # stack tracing support
  34. optStackTraceMsgs, # enable custom runtime msgs via `setFrameMsg`
  35. optLineTrace, # line tracing support (includes stack tracing)
  36. optByRef, # use pass by ref for objects
  37. # (for interfacing with C)
  38. optProfiler, # profiler turned on
  39. optImplicitStatic, # optimization: implicit at compile time
  40. # evaluation
  41. optTrMacros, # en/disable pattern matching
  42. optMemTracker,
  43. optSinkInference # 'sink T' inference
  44. optCursorInference
  45. optImportHidden
  46. optQuirky
  47. TOptions* = set[TOption]
  48. TGlobalOption* = enum
  49. gloptNone, optForceFullMake,
  50. optWasNimscript, # redundant with `cmdNimscript`, could be removed
  51. optListCmd, optCompileOnly, optNoLinking,
  52. optCDebug, # turn on debugging information
  53. optGenDynLib, # generate a dynamic library
  54. optGenStaticLib, # generate a static library
  55. optGenGuiApp, # generate a GUI application
  56. optGenScript, # generate a script file to compile the *.c files
  57. optGenCDeps, # generate a list of *.c files to be read by CMake
  58. optGenMapping, # generate a mapping file
  59. optRun, # run the compiled project
  60. optUseNimcache, # save artifacts (including binary) in $nimcache
  61. optStyleHint, # check that the names adhere to NEP-1
  62. optStyleError, # enforce that the names adhere to NEP-1
  63. optStyleUsages, # only enforce consistent **usages** of the symbol
  64. optSkipSystemConfigFile, # skip the system's cfg/nims config file
  65. optSkipProjConfigFile, # skip the project's cfg/nims config file
  66. optSkipUserConfigFile, # skip the users's cfg/nims config file
  67. optSkipParentConfigFiles, # skip parent dir's cfg/nims config files
  68. optNoMain, # do not generate a "main" proc
  69. optUseColors, # use colors for hints, warnings, and errors
  70. optThreads, # support for multi-threading
  71. optStdout, # output to stdout
  72. optThreadAnalysis, # thread analysis pass
  73. optTlsEmulation, # thread var emulation turned on
  74. optGenIndex # generate index file for documentation;
  75. optGenIndexOnly # generate only index file for documentation
  76. optNoImportdoc # disable loading external documentation files
  77. optEmbedOrigSrc # embed the original source in the generated code
  78. # also: generate header file
  79. optIdeDebug # idetools: debug mode
  80. optIdeTerse # idetools: use terse descriptions
  81. optIdeExceptionInlayHints
  82. optExcessiveStackTrace # fully qualified module filenames
  83. optShowAllMismatches # show all overloading resolution candidates
  84. optWholeProject # for 'doc': output any dependency
  85. optDocInternal # generate documentation for non-exported symbols
  86. optMixedMode # true if some module triggered C++ codegen
  87. optDeclaredLocs # show declaration locations in messages
  88. optNoNimblePath
  89. optHotCodeReloading
  90. optDynlibOverrideAll
  91. optSeqDestructors # active if the implementation uses the new
  92. # string/seq implementation based on destructors
  93. optTinyRtti # active if we use the new "tiny RTTI"
  94. # implementation
  95. optOwnedRefs # active if the Nim compiler knows about 'owned'.
  96. optMultiMethods
  97. optBenchmarkVM # Enables cpuTime() in the VM
  98. optProduceAsm # produce assembler code
  99. optPanics # turn panics (sysFatal) into a process termination
  100. optSourcemap
  101. optProfileVM # enable VM profiler
  102. optEnableDeepCopy # ORC specific: enable 'deepcopy' for all types.
  103. optShowNonExportedFields # for documentation: show fields that are not exported
  104. optJsBigInt64 # use bigints for 64-bit integers in JS
  105. TGlobalOptions* = set[TGlobalOption]
  106. const
  107. harmlessOptions* = {optForceFullMake, optNoLinking, optRun, optUseColors, optStdout}
  108. genSubDir* = RelativeDir"nimcache"
  109. NimExt* = "nim"
  110. RodExt* = "rod"
  111. HtmlExt* = "html"
  112. JsonExt* = "json"
  113. TagsExt* = "tags"
  114. TexExt* = "tex"
  115. IniExt* = "ini"
  116. DefaultConfig* = RelativeFile"nim.cfg"
  117. DefaultConfigNims* = RelativeFile"config.nims"
  118. DocConfig* = RelativeFile"nimdoc.cfg"
  119. DocTexConfig* = RelativeFile"nimdoc.tex.cfg"
  120. htmldocsDir* = htmldocsDirname.RelativeDir
  121. docRootDefault* = "@default" # using `@` instead of `$` to avoid shell quoting complications
  122. oKeepVariableNames* = true
  123. spellSuggestSecretSauce* = -1
  124. type
  125. TBackend* = enum
  126. backendInvalid = "" # for parseEnum
  127. backendC = "c"
  128. backendCpp = "cpp"
  129. backendJs = "js"
  130. backendObjc = "objc"
  131. # backendNimscript = "nimscript" # this could actually work
  132. # backendLlvm = "llvm" # probably not well supported; was cmdCompileToLLVM
  133. Command* = enum ## Nim's commands
  134. cmdNone # not yet processed command
  135. cmdUnknown # command unmapped
  136. cmdCompileToC, cmdCompileToCpp, cmdCompileToOC, cmdCompileToJS,
  137. cmdCrun # compile and run in nimache
  138. cmdTcc # run the project via TCC backend
  139. cmdCheck # semantic checking for whole project
  140. cmdM # only compile a single
  141. cmdParse # parse a single file (for debugging)
  142. cmdRod # .rod to some text representation (for debugging)
  143. cmdIdeTools # ide tools (e.g. nimsuggest)
  144. cmdNimscript # evaluate nimscript
  145. cmdDoc0
  146. cmdDoc # convert .nim doc comments to HTML
  147. cmdDoc2tex # convert .nim doc comments to LaTeX
  148. cmdRst2html # convert a reStructuredText file to HTML
  149. cmdRst2tex # convert a reStructuredText file to TeX
  150. cmdMd2html # convert a Markdown file to HTML
  151. cmdMd2tex # convert a Markdown file to TeX
  152. cmdJsondoc0
  153. cmdJsondoc
  154. cmdCtags
  155. cmdBuildindex
  156. cmdGendepend
  157. cmdDump
  158. cmdInteractive # start interactive session
  159. cmdNop
  160. cmdJsonscript # compile a .json build file
  161. # old unused: cmdInterpret, cmdDef: def feature (find definition for IDEs)
  162. const
  163. cmdBackends* = {cmdCompileToC, cmdCompileToCpp, cmdCompileToOC,
  164. cmdCompileToJS, cmdCrun}
  165. cmdDocLike* = {cmdDoc0, cmdDoc, cmdDoc2tex, cmdJsondoc0, cmdJsondoc,
  166. cmdCtags, cmdBuildindex}
  167. type
  168. TStringSeq* = seq[string]
  169. TGCMode* = enum # the selected GC
  170. gcUnselected = "unselected"
  171. gcNone = "none"
  172. gcBoehm = "boehm"
  173. gcRegions = "regions"
  174. gcArc = "arc"
  175. gcOrc = "orc"
  176. gcAtomicArc = "atomicArc"
  177. gcMarkAndSweep = "markAndSweep"
  178. gcHooks = "hooks"
  179. gcRefc = "refc"
  180. gcGo = "go"
  181. # gcRefc and the GCs that follow it use a write barrier,
  182. # as far as usesWriteBarrier() is concerned
  183. IdeCmd* = enum
  184. ideNone, ideSug, ideCon, ideDef, ideUse, ideDus, ideChk, ideChkFile, ideMod,
  185. ideHighlight, ideOutline, ideKnown, ideMsg, ideProject, ideGlobalSymbols,
  186. ideRecompile, ideChanged, ideType, ideDeclaration, ideExpand, ideInlayHints
  187. Feature* = enum ## experimental features; DO NOT RENAME THESE!
  188. dotOperators,
  189. callOperator,
  190. parallel,
  191. destructor,
  192. notnil,
  193. dynamicBindSym,
  194. forLoopMacros, # not experimental anymore; remains here for backwards compatibility
  195. caseStmtMacros, # ditto
  196. codeReordering,
  197. compiletimeFFI,
  198. ## This requires building nim with `-d:nimHasLibFFI`
  199. ## which itself requires `koch installdeps libffi`, see #10150
  200. ## Note: this feature can't be localized with {.push.}
  201. vmopsDanger,
  202. strictFuncs,
  203. views,
  204. strictNotNil,
  205. overloadableEnums, # deadcode
  206. strictEffects,
  207. unicodeOperators, # deadcode
  208. flexibleOptionalParams,
  209. strictDefs, # deadcode
  210. strictCaseObjects,
  211. inferGenericTypes,
  212. openSym, # remove nfDisabledOpenSym when this is default
  213. # alternative to above:
  214. genericsOpenSym
  215. vtables
  216. typeBoundOps
  217. LegacyFeature* = enum
  218. allowSemcheckedAstModification,
  219. ## Allows to modify a NimNode where the type has already been
  220. ## flagged with nfSem. If you actually do this, it will cause
  221. ## bugs.
  222. checkUnsignedConversions
  223. ## Historically and especially in version 1.0.0 of the language
  224. ## conversions to unsigned numbers were checked. In 1.0.4 they
  225. ## are not anymore.
  226. laxEffects
  227. ## Lax effects system prior to Nim 2.0.
  228. verboseTypeMismatch
  229. emitGenerics
  230. ## generics are emitted in the module that contains them.
  231. ## Useful for libraries that rely on local passC
  232. jsNoLambdaLifting
  233. ## Old transformation for closures in JS backend
  234. noStrictDefs
  235. ## disable "strictdefs"
  236. SymbolFilesOption* = enum
  237. disabledSf, writeOnlySf, readOnlySf, v2Sf, stressTest
  238. TSystemCC* = enum
  239. ccNone, ccGcc, ccNintendoSwitch, ccLLVM_Gcc, ccCLang, ccBcc, ccVcc,
  240. ccTcc, ccEnv, ccIcl, ccIcc, ccClangCl, ccHipcc, ccNvcc
  241. ExceptionSystem* = enum
  242. excNone, # no exception system selected yet
  243. excSetjmp, # setjmp based exception handling
  244. excCpp, # use C++'s native exception handling
  245. excGoto, # exception handling based on goto (should become the new default for C)
  246. excQuirky # quirky exception handling
  247. CfileFlag* {.pure.} = enum
  248. Cached, ## no need to recompile this time
  249. External ## file was introduced via .compile pragma
  250. Cfile* = object
  251. nimname*: string
  252. cname*, obj*: AbsoluteFile
  253. flags*: set[CfileFlag]
  254. customArgs*: string
  255. CfileList* = seq[Cfile]
  256. Suggest* = ref object
  257. section*: IdeCmd
  258. qualifiedPath*: seq[string]
  259. name*: ptr string # not used beyond sorting purposes; name is also
  260. # part of 'qualifiedPath'
  261. filePath*: string
  262. line*: int # Starts at 1
  263. column*: int # Starts at 0
  264. doc*: string # Not escaped (yet)
  265. forth*: string # type
  266. quality*: range[0..100] # matching quality
  267. isGlobal*: bool # is a global variable
  268. contextFits*: bool # type/non-type context matches
  269. prefix*: PrefixMatch
  270. symkind*: byte
  271. scope*, localUsages*, globalUsages*: int # more usages is better
  272. tokenLen*: int
  273. version*: int
  274. endLine*: uint16
  275. endCol*: int
  276. inlayHintInfo*: SuggestInlayHint
  277. Suggestions* = seq[Suggest]
  278. SuggestInlayHintKind* = enum
  279. sihkType = "Type",
  280. sihkParameter = "Parameter"
  281. sihkException = "Exception"
  282. SuggestInlayHint* = ref object
  283. kind*: SuggestInlayHintKind
  284. line*: int # Starts at 1
  285. column*: int # Starts at 0
  286. label*: string
  287. paddingLeft*: bool
  288. paddingRight*: bool
  289. allowInsert*: bool
  290. tooltip*: string
  291. ProfileInfo* = object
  292. time*: float
  293. count*: int
  294. ProfileData* = ref object
  295. data*: TableRef[TLineInfo, ProfileInfo]
  296. StdOrrKind* = enum
  297. stdOrrStdout
  298. stdOrrStderr
  299. FilenameOption* = enum
  300. foAbs # absolute path, e.g.: /pathto/bar/foo.nim
  301. foRelProject # relative to project path, e.g.: ../foo.nim
  302. foCanonical # canonical module name
  303. foLegacyRelProj # legacy, shortest of (foAbs, foRelProject)
  304. foName # lastPathPart, e.g.: foo.nim
  305. foStacktrace # if optExcessiveStackTrace: foAbs else: foName
  306. ConfigRef* {.acyclic.} = ref object ## every global configuration
  307. ## fields marked with '*' are subject to
  308. ## the incremental compilation mechanisms
  309. ## (+) means "part of the dependency"
  310. backend*: TBackend # set via `nim x` or `nim --backend:x`
  311. target*: Target # (+)
  312. linesCompiled*: int # all lines that have been compiled
  313. options*: TOptions # (+)
  314. globalOptions*: TGlobalOptions # (+)
  315. macrosToExpand*: StringTableRef
  316. arcToExpand*: StringTableRef
  317. m*: MsgConfig
  318. filenameOption*: FilenameOption # how to render paths in compiler messages
  319. unitSep*: string
  320. evalTemplateCounter*: int
  321. evalMacroCounter*: int
  322. exitcode*: int8
  323. cmd*: Command # raw command parsed as enum
  324. cmdInput*: string # input command
  325. projectIsCmd*: bool # whether we're compiling from a command input
  326. implicitCmd*: bool # whether some flag triggered an implicit `command`
  327. selectedGC*: TGCMode # the selected GC (+)
  328. exc*: ExceptionSystem
  329. hintProcessingDots*: bool # true for dots, false for filenames
  330. verbosity*: int # how verbose the compiler is
  331. numberOfProcessors*: int # number of processors
  332. lastCmdTime*: float # when caas is enabled, we measure each command
  333. symbolFiles*: SymbolFilesOption
  334. spellSuggestMax*: int # max number of spelling suggestions for typos
  335. cppDefines*: HashSet[string] # (*)
  336. headerFile*: string
  337. nimbasePattern*: string # pattern to find nimbase.h
  338. features*: set[Feature]
  339. legacyFeatures*: set[LegacyFeature]
  340. arguments*: string ## the arguments to be passed to the program that
  341. ## should be run
  342. ideCmd*: IdeCmd
  343. cCompiler*: TSystemCC # the used compiler
  344. modifiedyNotes*: TNoteKinds # notes that have been set/unset from either cmdline/configs
  345. cmdlineNotes*: TNoteKinds # notes that have been set/unset from cmdline
  346. foreignPackageNotes*: TNoteKinds
  347. notes*: TNoteKinds # notes after resolving all logic(defaults, verbosity)/cmdline/configs
  348. warningAsErrors*: TNoteKinds
  349. mainPackageNotes*: TNoteKinds
  350. mainPackageId*: int
  351. errorCounter*: int
  352. hintCounter*: int
  353. warnCounter*: int
  354. errorMax*: int
  355. maxLoopIterationsVM*: int ## VM: max iterations of all loops
  356. maxCallDepthVM*: int ## VM: max call depth
  357. isVmTrace*: bool
  358. configVars*: StringTableRef
  359. symbols*: StringTableRef ## We need to use a StringTableRef here as defined
  360. ## symbols are always guaranteed to be style
  361. ## insensitive. Otherwise hell would break lose.
  362. packageCache*: StringTableRef
  363. nimblePaths*: seq[AbsoluteDir]
  364. searchPaths*: seq[AbsoluteDir]
  365. lazyPaths*: seq[AbsoluteDir]
  366. outFile*: RelativeFile
  367. outDir*: AbsoluteDir
  368. jsonBuildFile*: AbsoluteFile
  369. prefixDir*, libpath*, nimcacheDir*: AbsoluteDir
  370. dllOverrides*, moduleOverrides*, cfileSpecificOptions*: StringTableRef
  371. projectName*: string # holds a name like 'nim'
  372. projectPath*: AbsoluteDir # holds a path like /home/alice/projects/nim/compiler/
  373. projectFull*: AbsoluteFile # projectPath/projectName
  374. projectIsStdin*: bool # whether we're compiling from stdin
  375. lastMsgWasDot*: set[StdOrrKind] # the last compiler message was a single '.'
  376. projectMainIdx*: FileIndex # the canonical path id of the main module
  377. projectMainIdx2*: FileIndex # consider merging with projectMainIdx
  378. command*: string # the main command (e.g. cc, check, scan, etc)
  379. commandArgs*: seq[string] # any arguments after the main command
  380. commandLine*: string
  381. extraCmds*: seq[string] # for writeJsonBuildInstructions
  382. implicitImports*: seq[string] # modules that are to be implicitly imported
  383. implicitIncludes*: seq[string] # modules that are to be implicitly included
  384. docSeeSrcUrl*: string # if empty, no seeSrc will be generated. \
  385. # The string uses the formatting variables `path` and `line`.
  386. docRoot*: string ## see nim --fullhelp for --docRoot
  387. docCmd*: string ## see nim --fullhelp for --docCmd
  388. configFiles*: seq[AbsoluteFile] # config files (cfg,nims)
  389. cIncludes*: seq[AbsoluteDir] # directories to search for included files
  390. cLibs*: seq[AbsoluteDir] # directories to search for lib files
  391. cLinkedLibs*: seq[string] # libraries to link
  392. externalToLink*: seq[string] # files to link in addition to the file
  393. # we compiled (*)
  394. linkOptionsCmd*: string
  395. compileOptionsCmd*: seq[string]
  396. linkOptions*: string # (*)
  397. compileOptions*: string # (*)
  398. cCompilerPath*: string
  399. toCompile*: CfileList # (*)
  400. suggestionResultHook*: proc (result: Suggest) {.closure.}
  401. suggestVersion*: int
  402. suggestMaxResults*: int
  403. lastLineInfo*: TLineInfo
  404. writelnHook*: proc (output: string) {.closure, gcsafe.}
  405. structuredErrorHook*: proc (config: ConfigRef; info: TLineInfo; msg: string;
  406. severity: Severity) {.closure, gcsafe.}
  407. cppCustomNamespace*: string
  408. nimMainPrefix*: string
  409. vmProfileData*: ProfileData
  410. expandProgress*: bool
  411. expandLevels*: int
  412. expandNodeResult*: string
  413. expandPosition*: TLineInfo
  414. currentConfigDir*: string # used for passPP only; absolute dir
  415. clientProcessId*: int
  416. proc assignIfDefault*[T](result: var T, val: T, def = default(T)) =
  417. ## if `result` was already assigned to a value (that wasn't `def`), this is a noop.
  418. if result == def: result = val
  419. template setErrorMaxHighMaybe*(conf: ConfigRef) =
  420. ## do not stop after first error (but honor --errorMax if provided)
  421. assignIfDefault(conf.errorMax, high(int))
  422. proc setNoteDefaults*(conf: ConfigRef, note: TNoteKind, enabled = true) =
  423. template fun(op) =
  424. conf.notes.op note
  425. conf.mainPackageNotes.op note
  426. conf.foreignPackageNotes.op note
  427. if enabled: fun(incl) else: fun(excl)
  428. proc setNote*(conf: ConfigRef, note: TNoteKind, enabled = true) =
  429. # see also `prepareConfigNotes` which sets notes
  430. if note notin conf.cmdlineNotes:
  431. if enabled: incl(conf.notes, note) else: excl(conf.notes, note)
  432. proc hasHint*(conf: ConfigRef, note: TNoteKind): bool =
  433. # ternary states instead of binary states would simplify logic
  434. if optHints notin conf.options: false
  435. elif note in {hintConf, hintProcessing}:
  436. # could add here other special notes like hintSource
  437. # these notes apply globally.
  438. note in conf.mainPackageNotes
  439. else: note in conf.notes
  440. proc hasWarn*(conf: ConfigRef, note: TNoteKind): bool {.inline.} =
  441. optWarns in conf.options and note in conf.notes
  442. proc hcrOn*(conf: ConfigRef): bool = return optHotCodeReloading in conf.globalOptions
  443. when false:
  444. template depConfigFields*(fn) {.dirty.} = # deadcode
  445. fn(target)
  446. fn(options)
  447. fn(globalOptions)
  448. fn(selectedGC)
  449. const oldExperimentalFeatures* = {dotOperators, callOperator, parallel}
  450. const
  451. ChecksOptions* = {optObjCheck, optFieldCheck, optRangeCheck,
  452. optOverflowCheck, optBoundsCheck, optAssert, optNaNCheck, optInfCheck,
  453. optStyleCheck}
  454. DefaultOptions* = {optObjCheck, optFieldCheck, optRangeCheck,
  455. optBoundsCheck, optOverflowCheck, optAssert, optWarns, optRefCheck,
  456. optHints, optStackTrace, optLineTrace, # consider adding `optStackTraceMsgs`
  457. optTrMacros, optStyleCheck, optCursorInference}
  458. DefaultGlobalOptions* = {optThreadAnalysis, optExcessiveStackTrace,
  459. optJsBigInt64}
  460. proc getSrcTimestamp(): DateTime =
  461. try:
  462. result = utc(fromUnix(parseInt(getEnv("SOURCE_DATE_EPOCH",
  463. "not a number"))))
  464. except ValueError:
  465. # Environment variable malformed.
  466. # https://reproducible-builds.org/specs/source-date-epoch/: "If the
  467. # value is malformed, the build process SHOULD exit with a non-zero
  468. # error code", which this doesn't do. This uses local time, because
  469. # that maintains compatibility with existing usage.
  470. result = utc getTime()
  471. proc getDateStr*(): string =
  472. result = format(getSrcTimestamp(), "yyyy-MM-dd")
  473. proc getClockStr*(): string =
  474. result = format(getSrcTimestamp(), "HH:mm:ss")
  475. template newPackageCache*(): untyped =
  476. newStringTable(when FileSystemCaseSensitive:
  477. modeCaseInsensitive
  478. else:
  479. modeCaseSensitive)
  480. proc newProfileData(): ProfileData =
  481. ProfileData(data: newTable[TLineInfo, ProfileInfo]())
  482. const foreignPackageNotesDefault* = {
  483. hintProcessing, warnUnknownMagic, hintQuitCalled, hintExecuting, hintUser, warnUser}
  484. proc isDefined*(conf: ConfigRef; symbol: string): bool
  485. when defined(nimDebugUtils):
  486. # this allows inserting debugging utilties in all modules that import `options`
  487. # with a single switch, which is useful when debugging compiler.
  488. import debugutils
  489. export debugutils
  490. proc initConfigRefCommon(conf: ConfigRef) =
  491. conf.selectedGC = gcUnselected
  492. conf.verbosity = 1
  493. conf.hintProcessingDots = true
  494. conf.options = DefaultOptions
  495. conf.globalOptions = DefaultGlobalOptions
  496. conf.filenameOption = foAbs
  497. conf.foreignPackageNotes = foreignPackageNotesDefault
  498. conf.notes = NotesVerbosity[1]
  499. conf.mainPackageNotes = NotesVerbosity[1]
  500. proc newConfigRef*(): ConfigRef =
  501. result = ConfigRef(
  502. cCompiler: ccGcc,
  503. macrosToExpand: newStringTable(modeStyleInsensitive),
  504. arcToExpand: newStringTable(modeStyleInsensitive),
  505. m: initMsgConfig(),
  506. cppDefines: initHashSet[string](),
  507. headerFile: "", features: {}, legacyFeatures: {},
  508. configVars: newStringTable(modeStyleInsensitive),
  509. symbols: newStringTable(modeStyleInsensitive),
  510. packageCache: newPackageCache(),
  511. searchPaths: @[],
  512. lazyPaths: @[],
  513. outFile: RelativeFile"",
  514. outDir: AbsoluteDir"",
  515. prefixDir: AbsoluteDir"",
  516. libpath: AbsoluteDir"", nimcacheDir: AbsoluteDir"",
  517. dllOverrides: newStringTable(modeCaseInsensitive),
  518. moduleOverrides: newStringTable(modeStyleInsensitive),
  519. cfileSpecificOptions: newStringTable(modeCaseSensitive),
  520. projectName: "", # holds a name like 'nim'
  521. projectPath: AbsoluteDir"", # holds a path like /home/alice/projects/nim/compiler/
  522. projectFull: AbsoluteFile"", # projectPath/projectName
  523. projectIsStdin: false, # whether we're compiling from stdin
  524. projectMainIdx: FileIndex(0'i32), # the canonical path id of the main module
  525. command: "", # the main command (e.g. cc, check, scan, etc)
  526. commandArgs: @[], # any arguments after the main command
  527. commandLine: "",
  528. implicitImports: @[], # modules that are to be implicitly imported
  529. implicitIncludes: @[], # modules that are to be implicitly included
  530. docSeeSrcUrl: "",
  531. cIncludes: @[], # directories to search for included files
  532. cLibs: @[], # directories to search for lib files
  533. cLinkedLibs: @[], # libraries to link
  534. backend: backendInvalid,
  535. externalToLink: @[],
  536. linkOptionsCmd: "",
  537. compileOptionsCmd: @[],
  538. linkOptions: "",
  539. compileOptions: "",
  540. ccompilerpath: "",
  541. toCompile: @[],
  542. arguments: "",
  543. suggestMaxResults: 10_000,
  544. maxLoopIterationsVM: 10_000_000,
  545. maxCallDepthVM: 2_000,
  546. vmProfileData: newProfileData(),
  547. spellSuggestMax: spellSuggestSecretSauce,
  548. currentConfigDir: ""
  549. )
  550. initConfigRefCommon(result)
  551. setTargetFromSystem(result.target)
  552. # enable colors by default on terminals
  553. if terminal.isatty(stderr):
  554. incl(result.globalOptions, optUseColors)
  555. when defined(nimDebugUtils):
  556. onNewConfigRef(result)
  557. proc newPartialConfigRef*(): ConfigRef =
  558. ## create a new ConfigRef that is only good enough for error reporting.
  559. when defined(nimDebugUtils):
  560. result = getConfigRef()
  561. else:
  562. result = ConfigRef()
  563. initConfigRefCommon(result)
  564. proc cppDefine*(c: ConfigRef; define: string) =
  565. c.cppDefines.incl define
  566. proc isDefined*(conf: ConfigRef; symbol: string): bool =
  567. if conf.symbols.hasKey(symbol):
  568. result = true
  569. elif cmpIgnoreStyle(symbol, CPU[conf.target.targetCPU].name) == 0:
  570. result = true
  571. elif cmpIgnoreStyle(symbol, platform.OS[conf.target.targetOS].name) == 0:
  572. result = true
  573. else:
  574. case symbol.normalize
  575. of "x86": result = conf.target.targetCPU == cpuI386
  576. of "itanium": result = conf.target.targetCPU == cpuIa64
  577. of "x8664": result = conf.target.targetCPU == cpuAmd64
  578. of "posix", "unix":
  579. result = conf.target.targetOS in {osLinux, osMorphos, osSkyos, osIrix, osPalmos,
  580. osQnx, osAtari, osAix,
  581. osHaiku, osVxWorks, osSolaris, osNetbsd,
  582. osFreebsd, osOpenbsd, osDragonfly, osMacosx, osIos,
  583. osAndroid, osNintendoSwitch, osFreeRTOS, osCrossos, osZephyr, osNuttX}
  584. of "linux":
  585. result = conf.target.targetOS in {osLinux, osAndroid}
  586. of "bsd":
  587. result = conf.target.targetOS in {osNetbsd, osFreebsd, osOpenbsd, osDragonfly, osCrossos}
  588. of "freebsd":
  589. result = conf.target.targetOS in {osFreebsd, osCrossos}
  590. of "emulatedthreadvars":
  591. result = platform.OS[conf.target.targetOS].props.contains(ospLacksThreadVars)
  592. of "msdos": result = conf.target.targetOS == osDos
  593. of "mswindows", "win32": result = conf.target.targetOS == osWindows
  594. of "macintosh":
  595. result = conf.target.targetOS in {osMacos, osMacosx, osIos}
  596. of "osx", "macosx":
  597. result = conf.target.targetOS in {osMacosx, osIos}
  598. of "sunos": result = conf.target.targetOS == osSolaris
  599. of "nintendoswitch":
  600. result = conf.target.targetOS == osNintendoSwitch
  601. of "freertos", "lwip":
  602. result = conf.target.targetOS == osFreeRTOS
  603. of "zephyr":
  604. result = conf.target.targetOS == osZephyr
  605. of "nuttx":
  606. result = conf.target.targetOS == osNuttX
  607. of "littleendian": result = CPU[conf.target.targetCPU].endian == littleEndian
  608. of "bigendian": result = CPU[conf.target.targetCPU].endian == bigEndian
  609. of "cpu8": result = CPU[conf.target.targetCPU].bit == 8
  610. of "cpu16": result = CPU[conf.target.targetCPU].bit == 16
  611. of "cpu32": result = CPU[conf.target.targetCPU].bit == 32
  612. of "cpu64": result = CPU[conf.target.targetCPU].bit == 64
  613. of "nimrawsetjmp":
  614. result = conf.target.targetOS in {osSolaris, osNetbsd, osFreebsd, osOpenbsd,
  615. osDragonfly, osMacosx}
  616. else: result = false
  617. template quitOrRaise*(conf: ConfigRef, msg = "") =
  618. # xxx in future work, consider whether to also intercept `msgQuit` calls
  619. if conf.isDefined("nimDebug"):
  620. raiseAssert msg
  621. else:
  622. quit(msg) # quits with QuitFailure
  623. proc importantComments*(conf: ConfigRef): bool {.inline.} = conf.cmd in cmdDocLike + {cmdIdeTools}
  624. proc usesWriteBarrier*(conf: ConfigRef): bool {.inline.} = conf.selectedGC >= gcRefc
  625. template compilationCachePresent*(conf: ConfigRef): untyped =
  626. false
  627. # conf.symbolFiles in {v2Sf, writeOnlySf}
  628. template optPreserveOrigSource*(conf: ConfigRef): untyped =
  629. optEmbedOrigSrc in conf.globalOptions
  630. proc mainCommandArg*(conf: ConfigRef): string =
  631. ## This is intended for commands like check or parse
  632. ## which will work on the main project file unless
  633. ## explicitly given a specific file argument
  634. if conf.commandArgs.len > 0:
  635. result = conf.commandArgs[0]
  636. else:
  637. result = conf.projectName
  638. proc existsConfigVar*(conf: ConfigRef; key: string): bool =
  639. result = hasKey(conf.configVars, key)
  640. proc getConfigVar*(conf: ConfigRef; key: string, default = ""): string =
  641. result = conf.configVars.getOrDefault(key, default)
  642. proc setConfigVar*(conf: ConfigRef; key, val: string) =
  643. conf.configVars[key] = val
  644. proc getOutFile*(conf: ConfigRef; filename: RelativeFile, ext: string): AbsoluteFile =
  645. # explains regression https://github.com/nim-lang/Nim/issues/6583#issuecomment-625711125
  646. # Yet another reason why "" should not mean "."; `""/something` should raise
  647. # instead of implying "" == "." as it's bug prone.
  648. doAssert conf.outDir.string.len > 0
  649. result = conf.outDir / changeFileExt(filename, ext)
  650. proc absOutFile*(conf: ConfigRef): AbsoluteFile =
  651. doAssert not conf.outDir.isEmpty
  652. doAssert not conf.outFile.isEmpty
  653. result = conf.outDir / conf.outFile
  654. when defined(posix):
  655. if dirExists(result.string): result.string.add ".out"
  656. proc prepareToWriteOutput*(conf: ConfigRef): AbsoluteFile =
  657. ## Create the output directory and returns a full path to the output file
  658. result = conf.absOutFile
  659. createDir result.string.parentDir
  660. proc getPrefixDir*(conf: ConfigRef): AbsoluteDir =
  661. ## Gets the prefix dir, usually the parent directory where the binary resides.
  662. ##
  663. ## This is overridden by some tools (namely nimsuggest) via the ``conf.prefixDir``
  664. ## field.
  665. ## This should resolve to root of nim sources, whether running nim from a local
  666. ## clone or using installed nim, so that these exist: `result/doc/advopt.txt`
  667. ## and `result/lib/system.nim`
  668. if not conf.prefixDir.isEmpty: result = conf.prefixDir
  669. else:
  670. let binParent = AbsoluteDir splitPath(getAppDir()).head
  671. when defined(posix):
  672. if binParent == AbsoluteDir"/usr":
  673. result = AbsoluteDir"/usr/lib/nim"
  674. elif binParent == AbsoluteDir"/usr/local":
  675. result = AbsoluteDir"/usr/local/lib/nim"
  676. else:
  677. result = binParent
  678. else:
  679. result = binParent
  680. proc setDefaultLibpath*(conf: ConfigRef) =
  681. # set default value (can be overwritten):
  682. if conf.libpath.isEmpty:
  683. # choose default libpath:
  684. var prefix = getPrefixDir(conf)
  685. conf.libpath = prefix / RelativeDir"lib"
  686. # Special rule to support other tools (nimble) which import the compiler
  687. # modules and make use of them.
  688. let realNimPath = findExe("nim")
  689. # Find out if $nim/../../lib/system.nim exists.
  690. let parentNimLibPath = realNimPath.parentDir.parentDir / "lib"
  691. if not fileExists(conf.libpath.string / "system.nim") and
  692. fileExists(parentNimLibPath / "system.nim"):
  693. conf.libpath = AbsoluteDir parentNimLibPath
  694. proc canonicalizePath*(conf: ConfigRef; path: AbsoluteFile): AbsoluteFile =
  695. result = AbsoluteFile path.string.expandFilename
  696. proc setFromProjectName*(conf: ConfigRef; projectName: string) =
  697. try:
  698. conf.projectFull = canonicalizePath(conf, AbsoluteFile projectName)
  699. except OSError:
  700. conf.projectFull = AbsoluteFile projectName
  701. let p = splitFile(conf.projectFull)
  702. let dir = if p.dir.isEmpty: AbsoluteDir getCurrentDir() else: p.dir
  703. try:
  704. conf.projectPath = AbsoluteDir canonicalizePath(conf, AbsoluteFile dir)
  705. except OSError:
  706. conf.projectPath = dir
  707. conf.projectName = p.name
  708. proc removeTrailingDirSep*(path: string): string =
  709. if (path.len > 0) and (path[^1] == DirSep):
  710. result = substr(path, 0, path.len - 2)
  711. else:
  712. result = path
  713. proc disableNimblePath*(conf: ConfigRef) =
  714. incl conf.globalOptions, optNoNimblePath
  715. conf.lazyPaths.setLen(0)
  716. conf.nimblePaths.setLen(0)
  717. proc clearNimblePath*(conf: ConfigRef) =
  718. conf.lazyPaths.setLen(0)
  719. conf.nimblePaths.setLen(0)
  720. include packagehandling
  721. proc getOsCacheDir(): string =
  722. when defined(posix):
  723. result = getEnv("XDG_CACHE_HOME", getHomeDir() / ".cache") / "nim"
  724. else:
  725. result = getHomeDir() / genSubDir.string
  726. proc getNimcacheDir*(conf: ConfigRef): AbsoluteDir =
  727. proc nimcacheSuffix(conf: ConfigRef): string =
  728. if conf.cmd == cmdCheck: "_check"
  729. elif isDefined(conf, "release") or isDefined(conf, "danger"): "_r"
  730. else: "_d"
  731. # XXX projectName should always be without a file extension!
  732. result =
  733. if not conf.nimcacheDir.isEmpty:
  734. conf.nimcacheDir
  735. elif conf.backend == backendJs:
  736. if conf.outDir.isEmpty:
  737. conf.projectPath / genSubDir
  738. else:
  739. conf.outDir / genSubDir
  740. else:
  741. AbsoluteDir(getOsCacheDir() / splitFile(conf.projectName).name &
  742. nimcacheSuffix(conf))
  743. proc pathSubs*(conf: ConfigRef; p, config: string): string =
  744. let home = removeTrailingDirSep(os.getHomeDir())
  745. result = unixToNativePath(p % [
  746. "nim", getPrefixDir(conf).string,
  747. "lib", conf.libpath.string,
  748. "home", home,
  749. "config", config,
  750. "projectname", conf.projectName,
  751. "projectpath", conf.projectPath.string,
  752. "projectdir", conf.projectPath.string,
  753. "nimcache", getNimcacheDir(conf).string]).expandTilde
  754. iterator nimbleSubs*(conf: ConfigRef; p: string): string =
  755. let pl = p.toLowerAscii
  756. if "$nimblepath" in pl or "$nimbledir" in pl:
  757. for i in countdown(conf.nimblePaths.len-1, 0):
  758. let nimblePath = removeTrailingDirSep(conf.nimblePaths[i].string)
  759. yield p % ["nimblepath", nimblePath, "nimbledir", nimblePath]
  760. else:
  761. yield p
  762. proc toGeneratedFile*(conf: ConfigRef; path: AbsoluteFile,
  763. ext: string): AbsoluteFile =
  764. ## converts "/home/a/mymodule.nim", "rod" to "/home/a/nimcache/mymodule.rod"
  765. result = getNimcacheDir(conf) / RelativeFile path.string.splitPath.tail.changeFileExt(ext)
  766. proc completeGeneratedFilePath*(conf: ConfigRef; f: AbsoluteFile,
  767. createSubDir: bool = true): AbsoluteFile =
  768. ## Return an absolute path of a generated intermediary file.
  769. ## Optionally creates the cache directory if `createSubDir` is `true`.
  770. let subdir = getNimcacheDir(conf)
  771. if createSubDir:
  772. try:
  773. createDir(subdir.string)
  774. except OSError:
  775. conf.quitOrRaise "cannot create directory: " & subdir.string
  776. result = subdir / RelativeFile f.string.splitPath.tail
  777. proc rawFindFile(conf: ConfigRef; f: RelativeFile; suppressStdlib: bool): AbsoluteFile =
  778. for it in conf.searchPaths:
  779. if suppressStdlib and it.string.startsWith(conf.libpath.string):
  780. continue
  781. result = it / f
  782. if fileExists(result):
  783. return canonicalizePath(conf, result)
  784. result = AbsoluteFile""
  785. proc rawFindFile2(conf: ConfigRef; f: RelativeFile): AbsoluteFile =
  786. for i, it in conf.lazyPaths:
  787. result = it / f
  788. if fileExists(result):
  789. # bring to front
  790. for j in countdown(i, 1):
  791. swap(conf.lazyPaths[j], conf.lazyPaths[j-1])
  792. return canonicalizePath(conf, result)
  793. result = AbsoluteFile""
  794. template patchModule(conf: ConfigRef) {.dirty.} =
  795. if not result.isEmpty and conf.moduleOverrides.len > 0:
  796. let key = getPackageName(conf, result.string) & "_" & splitFile(result).name
  797. if conf.moduleOverrides.hasKey(key):
  798. let ov = conf.moduleOverrides[key]
  799. if ov.len > 0: result = AbsoluteFile(ov)
  800. const stdlibDirs* = [
  801. "pure", "core", "arch",
  802. "pure/collections",
  803. "pure/concurrency",
  804. "pure/unidecode", "impure",
  805. "wrappers", "wrappers/linenoise",
  806. "windows", "posix", "js",
  807. "deprecated/pure"]
  808. const
  809. pkgPrefix = "pkg/"
  810. stdPrefix* = "std/"
  811. proc getRelativePathFromConfigPath*(conf: ConfigRef; f: AbsoluteFile, isTitle = false): RelativeFile =
  812. result = RelativeFile("")
  813. let f = $f
  814. if isTitle:
  815. for dir in stdlibDirs:
  816. let path = conf.libpath.string / dir / f.lastPathPart
  817. if path.cmpPaths(f) == 0:
  818. return RelativeFile(stdPrefix & f.splitFile.name)
  819. template search(paths) =
  820. for it in paths:
  821. let it = $it
  822. if f.isRelativeTo(it):
  823. return relativePath(f, it).RelativeFile
  824. search(conf.searchPaths)
  825. search(conf.lazyPaths)
  826. proc findFile*(conf: ConfigRef; f: string; suppressStdlib = false): AbsoluteFile =
  827. if f.isAbsolute:
  828. result = if f.fileExists: AbsoluteFile(f) else: AbsoluteFile""
  829. else:
  830. result = rawFindFile(conf, RelativeFile f, suppressStdlib)
  831. if result.isEmpty:
  832. result = rawFindFile(conf, RelativeFile f.toLowerAscii, suppressStdlib)
  833. if result.isEmpty:
  834. result = rawFindFile2(conf, RelativeFile f)
  835. if result.isEmpty:
  836. result = rawFindFile2(conf, RelativeFile f.toLowerAscii)
  837. patchModule(conf)
  838. proc findModule*(conf: ConfigRef; modulename, currentModule: string): AbsoluteFile =
  839. # returns path to module
  840. var m = addFileExt(modulename, NimExt)
  841. var hasRelativeDot = false
  842. if m.startsWith(pkgPrefix):
  843. result = findFile(conf, m.substr(pkgPrefix.len), suppressStdlib = true)
  844. else:
  845. if m.startsWith(stdPrefix):
  846. result = AbsoluteFile("")
  847. let stripped = m.substr(stdPrefix.len)
  848. for candidate in stdlibDirs:
  849. let path = (conf.libpath.string / candidate / stripped)
  850. if fileExists(path):
  851. result = AbsoluteFile path
  852. break
  853. else: # If prefixed with std/ why would we add the current module path!
  854. let currentPath = currentModule.splitFile.dir
  855. result = AbsoluteFile currentPath / m
  856. if m.startsWith('.') and not fileExists(result):
  857. result = AbsoluteFile ""
  858. hasRelativeDot = true
  859. if not fileExists(result) and not hasRelativeDot:
  860. result = findFile(conf, m)
  861. patchModule(conf)
  862. proc findProjectNimFile*(conf: ConfigRef; pkg: string): string =
  863. const extensions = [".nims", ".cfg", ".nimcfg", ".nimble"]
  864. var
  865. candidates: seq[string] = @[]
  866. dir = pkg
  867. prev = dir
  868. nimblepkg = ""
  869. let pkgname = pkg.lastPathPart()
  870. while true:
  871. for k, f in os.walkDir(dir, relative = true):
  872. if k == pcFile and f != "config.nims":
  873. let (_, name, ext) = splitFile(f)
  874. if ext in extensions:
  875. let x = changeFileExt(dir / name, ".nim")
  876. if fileExists(x):
  877. candidates.add x
  878. if ext == ".nimble":
  879. if nimblepkg.len == 0:
  880. nimblepkg = name
  881. # Since nimble packages can have their source in a subfolder,
  882. # check the last folder we were in for a possible match.
  883. if dir != prev:
  884. let x = prev / x.extractFilename()
  885. if fileExists(x):
  886. candidates.add x
  887. else:
  888. # If we found more than one nimble file, chances are that we
  889. # missed the real project file, or this is an invalid nimble
  890. # package. Either way, bailing is the better choice.
  891. return ""
  892. let pkgname = if nimblepkg.len > 0: nimblepkg else: pkgname
  893. for c in candidates:
  894. if pkgname in c.extractFilename(): return c
  895. if candidates.len > 0:
  896. return candidates[0]
  897. prev = dir
  898. dir = parentDir(dir)
  899. if dir == "": break
  900. return ""
  901. proc canonicalImportAux*(conf: ConfigRef, file: AbsoluteFile): string =
  902. ##[
  903. Shows the canonical module import, e.g.:
  904. system, std/tables, fusion/pointers, system/assertions, std/private/asciitables
  905. ]##
  906. var ret = getRelativePathFromConfigPath(conf, file, isTitle = true)
  907. let dir = getNimbleFile(conf, $file).parentDir.AbsoluteDir
  908. if not dir.isEmpty:
  909. let relPath = relativeTo(file, dir)
  910. if not relPath.isEmpty and (ret.isEmpty or relPath.string.len < ret.string.len):
  911. ret = relPath
  912. if ret.isEmpty:
  913. ret = relativeTo(file, conf.projectPath)
  914. result = ret.string
  915. proc canonicalImport*(conf: ConfigRef, file: AbsoluteFile): string =
  916. let ret = canonicalImportAux(conf, file)
  917. result = ret.nativeToUnixPath.changeFileExt("")
  918. proc canonDynlibName(s: string): string =
  919. let start = if s.startsWith("lib"): 3 else: 0
  920. let ende = strutils.find(s, {'(', ')', '.'})
  921. if ende >= 0:
  922. result = s.substr(start, ende-1)
  923. else:
  924. result = s.substr(start)
  925. proc inclDynlibOverride*(conf: ConfigRef; lib: string) =
  926. conf.dllOverrides[lib.canonDynlibName] = "true"
  927. proc isDynlibOverride*(conf: ConfigRef; lib: string): bool =
  928. result = optDynlibOverrideAll in conf.globalOptions or
  929. conf.dllOverrides.hasKey(lib.canonDynlibName)
  930. proc showNonExportedFields*(conf: ConfigRef) =
  931. incl(conf.globalOptions, optShowNonExportedFields)
  932. proc expandDone*(conf: ConfigRef): bool =
  933. result = conf.ideCmd == ideExpand and conf.expandLevels == 0 and conf.expandProgress
  934. proc parseIdeCmd*(s: string): IdeCmd =
  935. case s:
  936. of "sug": ideSug
  937. of "con": ideCon
  938. of "def": ideDef
  939. of "use": ideUse
  940. of "dus": ideDus
  941. of "chk": ideChk
  942. of "chkFile": ideChkFile
  943. of "mod": ideMod
  944. of "highlight": ideHighlight
  945. of "outline": ideOutline
  946. of "known": ideKnown
  947. of "msg": ideMsg
  948. of "project": ideProject
  949. of "globalSymbols": ideGlobalSymbols
  950. of "recompile": ideRecompile
  951. of "changed": ideChanged
  952. of "type": ideType
  953. else: ideNone
  954. proc `$`*(c: IdeCmd): string =
  955. case c:
  956. of ideSug: "sug"
  957. of ideCon: "con"
  958. of ideDef: "def"
  959. of ideUse: "use"
  960. of ideDus: "dus"
  961. of ideChk: "chk"
  962. of ideChkFile: "chkFile"
  963. of ideMod: "mod"
  964. of ideNone: "none"
  965. of ideHighlight: "highlight"
  966. of ideOutline: "outline"
  967. of ideKnown: "known"
  968. of ideMsg: "msg"
  969. of ideProject: "project"
  970. of ideGlobalSymbols: "globalSymbols"
  971. of ideDeclaration: "declaration"
  972. of ideExpand: "expand"
  973. of ideRecompile: "recompile"
  974. of ideChanged: "changed"
  975. of ideType: "type"
  976. of ideInlayHints: "inlayHints"
  977. proc floatInt64Align*(conf: ConfigRef): int16 =
  978. ## Returns either 4 or 8 depending on reasons.
  979. if conf != nil and conf.target.targetCPU == cpuI386:
  980. #on Linux/BSD i386, double are aligned to 4bytes (except with -malign-double)
  981. if conf.target.targetOS != osWindows:
  982. # on i386 for all known POSIX systems, 64bits ints are aligned
  983. # to 4bytes (except with -malign-double)
  984. return 4
  985. return 8