options.nim 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091
  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,
  210. strictCaseObjects,
  211. inferGenericTypes,
  212. openSym, # remove nfDisabledOpenSym when this is default
  213. # alternative to above:
  214. genericsOpenSym
  215. vtables
  216. LegacyFeature* = enum
  217. allowSemcheckedAstModification,
  218. ## Allows to modify a NimNode where the type has already been
  219. ## flagged with nfSem. If you actually do this, it will cause
  220. ## bugs.
  221. checkUnsignedConversions
  222. ## Historically and especially in version 1.0.0 of the language
  223. ## conversions to unsigned numbers were checked. In 1.0.4 they
  224. ## are not anymore.
  225. laxEffects
  226. ## Lax effects system prior to Nim 2.0.
  227. verboseTypeMismatch
  228. emitGenerics
  229. ## generics are emitted in the module that contains them.
  230. ## Useful for libraries that rely on local passC
  231. jsNoLambdaLifting
  232. ## Old transformation for closures in JS backend
  233. SymbolFilesOption* = enum
  234. disabledSf, writeOnlySf, readOnlySf, v2Sf, stressTest
  235. TSystemCC* = enum
  236. ccNone, ccGcc, ccNintendoSwitch, ccLLVM_Gcc, ccCLang, ccBcc, ccVcc,
  237. ccTcc, ccEnv, ccIcl, ccIcc, ccClangCl, ccHipcc, ccNvcc
  238. ExceptionSystem* = enum
  239. excNone, # no exception system selected yet
  240. excSetjmp, # setjmp based exception handling
  241. excCpp, # use C++'s native exception handling
  242. excGoto, # exception handling based on goto (should become the new default for C)
  243. excQuirky # quirky exception handling
  244. CfileFlag* {.pure.} = enum
  245. Cached, ## no need to recompile this time
  246. External ## file was introduced via .compile pragma
  247. Cfile* = object
  248. nimname*: string
  249. cname*, obj*: AbsoluteFile
  250. flags*: set[CfileFlag]
  251. customArgs*: string
  252. CfileList* = seq[Cfile]
  253. Suggest* = ref object
  254. section*: IdeCmd
  255. qualifiedPath*: seq[string]
  256. name*: ptr string # not used beyond sorting purposes; name is also
  257. # part of 'qualifiedPath'
  258. filePath*: string
  259. line*: int # Starts at 1
  260. column*: int # Starts at 0
  261. doc*: string # Not escaped (yet)
  262. forth*: string # type
  263. quality*: range[0..100] # matching quality
  264. isGlobal*: bool # is a global variable
  265. contextFits*: bool # type/non-type context matches
  266. prefix*: PrefixMatch
  267. symkind*: byte
  268. scope*, localUsages*, globalUsages*: int # more usages is better
  269. tokenLen*: int
  270. version*: int
  271. endLine*: uint16
  272. endCol*: int
  273. inlayHintInfo*: SuggestInlayHint
  274. Suggestions* = seq[Suggest]
  275. SuggestInlayHintKind* = enum
  276. sihkType = "Type",
  277. sihkParameter = "Parameter"
  278. sihkException = "Exception"
  279. SuggestInlayHint* = ref object
  280. kind*: SuggestInlayHintKind
  281. line*: int # Starts at 1
  282. column*: int # Starts at 0
  283. label*: string
  284. paddingLeft*: bool
  285. paddingRight*: bool
  286. allowInsert*: bool
  287. tooltip*: string
  288. ProfileInfo* = object
  289. time*: float
  290. count*: int
  291. ProfileData* = ref object
  292. data*: TableRef[TLineInfo, ProfileInfo]
  293. StdOrrKind* = enum
  294. stdOrrStdout
  295. stdOrrStderr
  296. FilenameOption* = enum
  297. foAbs # absolute path, e.g.: /pathto/bar/foo.nim
  298. foRelProject # relative to project path, e.g.: ../foo.nim
  299. foCanonical # canonical module name
  300. foLegacyRelProj # legacy, shortest of (foAbs, foRelProject)
  301. foName # lastPathPart, e.g.: foo.nim
  302. foStacktrace # if optExcessiveStackTrace: foAbs else: foName
  303. ConfigRef* {.acyclic.} = ref object ## every global configuration
  304. ## fields marked with '*' are subject to
  305. ## the incremental compilation mechanisms
  306. ## (+) means "part of the dependency"
  307. backend*: TBackend # set via `nim x` or `nim --backend:x`
  308. target*: Target # (+)
  309. linesCompiled*: int # all lines that have been compiled
  310. options*: TOptions # (+)
  311. globalOptions*: TGlobalOptions # (+)
  312. macrosToExpand*: StringTableRef
  313. arcToExpand*: StringTableRef
  314. m*: MsgConfig
  315. filenameOption*: FilenameOption # how to render paths in compiler messages
  316. unitSep*: string
  317. evalTemplateCounter*: int
  318. evalMacroCounter*: int
  319. exitcode*: int8
  320. cmd*: Command # raw command parsed as enum
  321. cmdInput*: string # input command
  322. projectIsCmd*: bool # whether we're compiling from a command input
  323. implicitCmd*: bool # whether some flag triggered an implicit `command`
  324. selectedGC*: TGCMode # the selected GC (+)
  325. exc*: ExceptionSystem
  326. hintProcessingDots*: bool # true for dots, false for filenames
  327. verbosity*: int # how verbose the compiler is
  328. numberOfProcessors*: int # number of processors
  329. lastCmdTime*: float # when caas is enabled, we measure each command
  330. symbolFiles*: SymbolFilesOption
  331. spellSuggestMax*: int # max number of spelling suggestions for typos
  332. cppDefines*: HashSet[string] # (*)
  333. headerFile*: string
  334. nimbasePattern*: string # pattern to find nimbase.h
  335. features*: set[Feature]
  336. legacyFeatures*: set[LegacyFeature]
  337. arguments*: string ## the arguments to be passed to the program that
  338. ## should be run
  339. ideCmd*: IdeCmd
  340. cCompiler*: TSystemCC # the used compiler
  341. modifiedyNotes*: TNoteKinds # notes that have been set/unset from either cmdline/configs
  342. cmdlineNotes*: TNoteKinds # notes that have been set/unset from cmdline
  343. foreignPackageNotes*: TNoteKinds
  344. notes*: TNoteKinds # notes after resolving all logic(defaults, verbosity)/cmdline/configs
  345. warningAsErrors*: TNoteKinds
  346. mainPackageNotes*: TNoteKinds
  347. mainPackageId*: int
  348. errorCounter*: int
  349. hintCounter*: int
  350. warnCounter*: int
  351. errorMax*: int
  352. maxLoopIterationsVM*: int ## VM: max iterations of all loops
  353. isVmTrace*: bool
  354. configVars*: StringTableRef
  355. symbols*: StringTableRef ## We need to use a StringTableRef here as defined
  356. ## symbols are always guaranteed to be style
  357. ## insensitive. Otherwise hell would break lose.
  358. packageCache*: StringTableRef
  359. nimblePaths*: seq[AbsoluteDir]
  360. searchPaths*: seq[AbsoluteDir]
  361. lazyPaths*: seq[AbsoluteDir]
  362. outFile*: RelativeFile
  363. outDir*: AbsoluteDir
  364. jsonBuildFile*: AbsoluteFile
  365. prefixDir*, libpath*, nimcacheDir*: AbsoluteDir
  366. dllOverrides*, moduleOverrides*, cfileSpecificOptions*: StringTableRef
  367. projectName*: string # holds a name like 'nim'
  368. projectPath*: AbsoluteDir # holds a path like /home/alice/projects/nim/compiler/
  369. projectFull*: AbsoluteFile # projectPath/projectName
  370. projectIsStdin*: bool # whether we're compiling from stdin
  371. lastMsgWasDot*: set[StdOrrKind] # the last compiler message was a single '.'
  372. projectMainIdx*: FileIndex # the canonical path id of the main module
  373. projectMainIdx2*: FileIndex # consider merging with projectMainIdx
  374. command*: string # the main command (e.g. cc, check, scan, etc)
  375. commandArgs*: seq[string] # any arguments after the main command
  376. commandLine*: string
  377. extraCmds*: seq[string] # for writeJsonBuildInstructions
  378. implicitImports*: seq[string] # modules that are to be implicitly imported
  379. implicitIncludes*: seq[string] # modules that are to be implicitly included
  380. docSeeSrcUrl*: string # if empty, no seeSrc will be generated. \
  381. # The string uses the formatting variables `path` and `line`.
  382. docRoot*: string ## see nim --fullhelp for --docRoot
  383. docCmd*: string ## see nim --fullhelp for --docCmd
  384. configFiles*: seq[AbsoluteFile] # config files (cfg,nims)
  385. cIncludes*: seq[AbsoluteDir] # directories to search for included files
  386. cLibs*: seq[AbsoluteDir] # directories to search for lib files
  387. cLinkedLibs*: seq[string] # libraries to link
  388. externalToLink*: seq[string] # files to link in addition to the file
  389. # we compiled (*)
  390. linkOptionsCmd*: string
  391. compileOptionsCmd*: seq[string]
  392. linkOptions*: string # (*)
  393. compileOptions*: string # (*)
  394. cCompilerPath*: string
  395. toCompile*: CfileList # (*)
  396. suggestionResultHook*: proc (result: Suggest) {.closure.}
  397. suggestVersion*: int
  398. suggestMaxResults*: int
  399. lastLineInfo*: TLineInfo
  400. writelnHook*: proc (output: string) {.closure, gcsafe.}
  401. structuredErrorHook*: proc (config: ConfigRef; info: TLineInfo; msg: string;
  402. severity: Severity) {.closure, gcsafe.}
  403. cppCustomNamespace*: string
  404. nimMainPrefix*: string
  405. vmProfileData*: ProfileData
  406. expandProgress*: bool
  407. expandLevels*: int
  408. expandNodeResult*: string
  409. expandPosition*: TLineInfo
  410. currentConfigDir*: string # used for passPP only; absolute dir
  411. clientProcessId*: int
  412. proc assignIfDefault*[T](result: var T, val: T, def = default(T)) =
  413. ## if `result` was already assigned to a value (that wasn't `def`), this is a noop.
  414. if result == def: result = val
  415. template setErrorMaxHighMaybe*(conf: ConfigRef) =
  416. ## do not stop after first error (but honor --errorMax if provided)
  417. assignIfDefault(conf.errorMax, high(int))
  418. proc setNoteDefaults*(conf: ConfigRef, note: TNoteKind, enabled = true) =
  419. template fun(op) =
  420. conf.notes.op note
  421. conf.mainPackageNotes.op note
  422. conf.foreignPackageNotes.op note
  423. if enabled: fun(incl) else: fun(excl)
  424. proc setNote*(conf: ConfigRef, note: TNoteKind, enabled = true) =
  425. # see also `prepareConfigNotes` which sets notes
  426. if note notin conf.cmdlineNotes:
  427. if enabled: incl(conf.notes, note) else: excl(conf.notes, note)
  428. proc hasHint*(conf: ConfigRef, note: TNoteKind): bool =
  429. # ternary states instead of binary states would simplify logic
  430. if optHints notin conf.options: false
  431. elif note in {hintConf, hintProcessing}:
  432. # could add here other special notes like hintSource
  433. # these notes apply globally.
  434. note in conf.mainPackageNotes
  435. else: note in conf.notes
  436. proc hasWarn*(conf: ConfigRef, note: TNoteKind): bool {.inline.} =
  437. optWarns in conf.options and note in conf.notes
  438. proc hcrOn*(conf: ConfigRef): bool = return optHotCodeReloading in conf.globalOptions
  439. when false:
  440. template depConfigFields*(fn) {.dirty.} = # deadcode
  441. fn(target)
  442. fn(options)
  443. fn(globalOptions)
  444. fn(selectedGC)
  445. const oldExperimentalFeatures* = {dotOperators, callOperator, parallel}
  446. const
  447. ChecksOptions* = {optObjCheck, optFieldCheck, optRangeCheck,
  448. optOverflowCheck, optBoundsCheck, optAssert, optNaNCheck, optInfCheck,
  449. optStyleCheck}
  450. DefaultOptions* = {optObjCheck, optFieldCheck, optRangeCheck,
  451. optBoundsCheck, optOverflowCheck, optAssert, optWarns, optRefCheck,
  452. optHints, optStackTrace, optLineTrace, # consider adding `optStackTraceMsgs`
  453. optTrMacros, optStyleCheck, optCursorInference}
  454. DefaultGlobalOptions* = {optThreadAnalysis, optExcessiveStackTrace,
  455. optJsBigInt64}
  456. proc getSrcTimestamp(): DateTime =
  457. try:
  458. result = utc(fromUnix(parseInt(getEnv("SOURCE_DATE_EPOCH",
  459. "not a number"))))
  460. except ValueError:
  461. # Environment variable malformed.
  462. # https://reproducible-builds.org/specs/source-date-epoch/: "If the
  463. # value is malformed, the build process SHOULD exit with a non-zero
  464. # error code", which this doesn't do. This uses local time, because
  465. # that maintains compatibility with existing usage.
  466. result = utc getTime()
  467. proc getDateStr*(): string =
  468. result = format(getSrcTimestamp(), "yyyy-MM-dd")
  469. proc getClockStr*(): string =
  470. result = format(getSrcTimestamp(), "HH:mm:ss")
  471. template newPackageCache*(): untyped =
  472. newStringTable(when FileSystemCaseSensitive:
  473. modeCaseInsensitive
  474. else:
  475. modeCaseSensitive)
  476. proc newProfileData(): ProfileData =
  477. ProfileData(data: newTable[TLineInfo, ProfileInfo]())
  478. const foreignPackageNotesDefault* = {
  479. hintProcessing, warnUnknownMagic, hintQuitCalled, hintExecuting, hintUser, warnUser}
  480. proc isDefined*(conf: ConfigRef; symbol: string): bool
  481. when defined(nimDebugUtils):
  482. # this allows inserting debugging utilties in all modules that import `options`
  483. # with a single switch, which is useful when debugging compiler.
  484. import debugutils
  485. export debugutils
  486. proc initConfigRefCommon(conf: ConfigRef) =
  487. conf.selectedGC = gcUnselected
  488. conf.verbosity = 1
  489. conf.hintProcessingDots = true
  490. conf.options = DefaultOptions
  491. conf.globalOptions = DefaultGlobalOptions
  492. conf.filenameOption = foAbs
  493. conf.foreignPackageNotes = foreignPackageNotesDefault
  494. conf.notes = NotesVerbosity[1]
  495. conf.mainPackageNotes = NotesVerbosity[1]
  496. proc newConfigRef*(): ConfigRef =
  497. result = ConfigRef(
  498. cCompiler: ccGcc,
  499. macrosToExpand: newStringTable(modeStyleInsensitive),
  500. arcToExpand: newStringTable(modeStyleInsensitive),
  501. m: initMsgConfig(),
  502. cppDefines: initHashSet[string](),
  503. headerFile: "", features: {}, legacyFeatures: {},
  504. configVars: newStringTable(modeStyleInsensitive),
  505. symbols: newStringTable(modeStyleInsensitive),
  506. packageCache: newPackageCache(),
  507. searchPaths: @[],
  508. lazyPaths: @[],
  509. outFile: RelativeFile"",
  510. outDir: AbsoluteDir"",
  511. prefixDir: AbsoluteDir"",
  512. libpath: AbsoluteDir"", nimcacheDir: AbsoluteDir"",
  513. dllOverrides: newStringTable(modeCaseInsensitive),
  514. moduleOverrides: newStringTable(modeStyleInsensitive),
  515. cfileSpecificOptions: newStringTable(modeCaseSensitive),
  516. projectName: "", # holds a name like 'nim'
  517. projectPath: AbsoluteDir"", # holds a path like /home/alice/projects/nim/compiler/
  518. projectFull: AbsoluteFile"", # projectPath/projectName
  519. projectIsStdin: false, # whether we're compiling from stdin
  520. projectMainIdx: FileIndex(0'i32), # the canonical path id of the main module
  521. command: "", # the main command (e.g. cc, check, scan, etc)
  522. commandArgs: @[], # any arguments after the main command
  523. commandLine: "",
  524. implicitImports: @[], # modules that are to be implicitly imported
  525. implicitIncludes: @[], # modules that are to be implicitly included
  526. docSeeSrcUrl: "",
  527. cIncludes: @[], # directories to search for included files
  528. cLibs: @[], # directories to search for lib files
  529. cLinkedLibs: @[], # libraries to link
  530. backend: backendInvalid,
  531. externalToLink: @[],
  532. linkOptionsCmd: "",
  533. compileOptionsCmd: @[],
  534. linkOptions: "",
  535. compileOptions: "",
  536. ccompilerpath: "",
  537. toCompile: @[],
  538. arguments: "",
  539. suggestMaxResults: 10_000,
  540. maxLoopIterationsVM: 10_000_000,
  541. vmProfileData: newProfileData(),
  542. spellSuggestMax: spellSuggestSecretSauce,
  543. currentConfigDir: ""
  544. )
  545. initConfigRefCommon(result)
  546. setTargetFromSystem(result.target)
  547. # enable colors by default on terminals
  548. if terminal.isatty(stderr):
  549. incl(result.globalOptions, optUseColors)
  550. when defined(nimDebugUtils):
  551. onNewConfigRef(result)
  552. proc newPartialConfigRef*(): ConfigRef =
  553. ## create a new ConfigRef that is only good enough for error reporting.
  554. when defined(nimDebugUtils):
  555. result = getConfigRef()
  556. else:
  557. result = ConfigRef()
  558. initConfigRefCommon(result)
  559. proc cppDefine*(c: ConfigRef; define: string) =
  560. c.cppDefines.incl define
  561. proc isDefined*(conf: ConfigRef; symbol: string): bool =
  562. if conf.symbols.hasKey(symbol):
  563. result = true
  564. elif cmpIgnoreStyle(symbol, CPU[conf.target.targetCPU].name) == 0:
  565. result = true
  566. elif cmpIgnoreStyle(symbol, platform.OS[conf.target.targetOS].name) == 0:
  567. result = true
  568. else:
  569. case symbol.normalize
  570. of "x86": result = conf.target.targetCPU == cpuI386
  571. of "itanium": result = conf.target.targetCPU == cpuIa64
  572. of "x8664": result = conf.target.targetCPU == cpuAmd64
  573. of "posix", "unix":
  574. result = conf.target.targetOS in {osLinux, osMorphos, osSkyos, osIrix, osPalmos,
  575. osQnx, osAtari, osAix,
  576. osHaiku, osVxWorks, osSolaris, osNetbsd,
  577. osFreebsd, osOpenbsd, osDragonfly, osMacosx, osIos,
  578. osAndroid, osNintendoSwitch, osFreeRTOS, osCrossos, osZephyr, osNuttX}
  579. of "linux":
  580. result = conf.target.targetOS in {osLinux, osAndroid}
  581. of "bsd":
  582. result = conf.target.targetOS in {osNetbsd, osFreebsd, osOpenbsd, osDragonfly, osCrossos}
  583. of "freebsd":
  584. result = conf.target.targetOS in {osFreebsd, osCrossos}
  585. of "emulatedthreadvars":
  586. result = platform.OS[conf.target.targetOS].props.contains(ospLacksThreadVars)
  587. of "msdos": result = conf.target.targetOS == osDos
  588. of "mswindows", "win32": result = conf.target.targetOS == osWindows
  589. of "macintosh":
  590. result = conf.target.targetOS in {osMacos, osMacosx, osIos}
  591. of "osx", "macosx":
  592. result = conf.target.targetOS in {osMacosx, osIos}
  593. of "sunos": result = conf.target.targetOS == osSolaris
  594. of "nintendoswitch":
  595. result = conf.target.targetOS == osNintendoSwitch
  596. of "freertos", "lwip":
  597. result = conf.target.targetOS == osFreeRTOS
  598. of "zephyr":
  599. result = conf.target.targetOS == osZephyr
  600. of "nuttx":
  601. result = conf.target.targetOS == osNuttX
  602. of "littleendian": result = CPU[conf.target.targetCPU].endian == littleEndian
  603. of "bigendian": result = CPU[conf.target.targetCPU].endian == bigEndian
  604. of "cpu8": result = CPU[conf.target.targetCPU].bit == 8
  605. of "cpu16": result = CPU[conf.target.targetCPU].bit == 16
  606. of "cpu32": result = CPU[conf.target.targetCPU].bit == 32
  607. of "cpu64": result = CPU[conf.target.targetCPU].bit == 64
  608. of "nimrawsetjmp":
  609. result = conf.target.targetOS in {osSolaris, osNetbsd, osFreebsd, osOpenbsd,
  610. osDragonfly, osMacosx}
  611. else: result = false
  612. template quitOrRaise*(conf: ConfigRef, msg = "") =
  613. # xxx in future work, consider whether to also intercept `msgQuit` calls
  614. if conf.isDefined("nimDebug"):
  615. raiseAssert msg
  616. else:
  617. quit(msg) # quits with QuitFailure
  618. proc importantComments*(conf: ConfigRef): bool {.inline.} = conf.cmd in cmdDocLike + {cmdIdeTools}
  619. proc usesWriteBarrier*(conf: ConfigRef): bool {.inline.} = conf.selectedGC >= gcRefc
  620. template compilationCachePresent*(conf: ConfigRef): untyped =
  621. false
  622. # conf.symbolFiles in {v2Sf, writeOnlySf}
  623. template optPreserveOrigSource*(conf: ConfigRef): untyped =
  624. optEmbedOrigSrc in conf.globalOptions
  625. proc mainCommandArg*(conf: ConfigRef): string =
  626. ## This is intended for commands like check or parse
  627. ## which will work on the main project file unless
  628. ## explicitly given a specific file argument
  629. if conf.commandArgs.len > 0:
  630. result = conf.commandArgs[0]
  631. else:
  632. result = conf.projectName
  633. proc existsConfigVar*(conf: ConfigRef; key: string): bool =
  634. result = hasKey(conf.configVars, key)
  635. proc getConfigVar*(conf: ConfigRef; key: string, default = ""): string =
  636. result = conf.configVars.getOrDefault(key, default)
  637. proc setConfigVar*(conf: ConfigRef; key, val: string) =
  638. conf.configVars[key] = val
  639. proc getOutFile*(conf: ConfigRef; filename: RelativeFile, ext: string): AbsoluteFile =
  640. # explains regression https://github.com/nim-lang/Nim/issues/6583#issuecomment-625711125
  641. # Yet another reason why "" should not mean "."; `""/something` should raise
  642. # instead of implying "" == "." as it's bug prone.
  643. doAssert conf.outDir.string.len > 0
  644. result = conf.outDir / changeFileExt(filename, ext)
  645. proc absOutFile*(conf: ConfigRef): AbsoluteFile =
  646. doAssert not conf.outDir.isEmpty
  647. doAssert not conf.outFile.isEmpty
  648. result = conf.outDir / conf.outFile
  649. when defined(posix):
  650. if dirExists(result.string): result.string.add ".out"
  651. proc prepareToWriteOutput*(conf: ConfigRef): AbsoluteFile =
  652. ## Create the output directory and returns a full path to the output file
  653. result = conf.absOutFile
  654. createDir result.string.parentDir
  655. proc getPrefixDir*(conf: ConfigRef): AbsoluteDir =
  656. ## Gets the prefix dir, usually the parent directory where the binary resides.
  657. ##
  658. ## This is overridden by some tools (namely nimsuggest) via the ``conf.prefixDir``
  659. ## field.
  660. ## This should resolve to root of nim sources, whether running nim from a local
  661. ## clone or using installed nim, so that these exist: `result/doc/advopt.txt`
  662. ## and `result/lib/system.nim`
  663. if not conf.prefixDir.isEmpty: result = conf.prefixDir
  664. else:
  665. let binParent = AbsoluteDir splitPath(getAppDir()).head
  666. when defined(posix):
  667. if binParent == AbsoluteDir"/usr":
  668. result = AbsoluteDir"/usr/lib/nim"
  669. elif binParent == AbsoluteDir"/usr/local":
  670. result = AbsoluteDir"/usr/local/lib/nim"
  671. else:
  672. result = binParent
  673. else:
  674. result = binParent
  675. proc setDefaultLibpath*(conf: ConfigRef) =
  676. # set default value (can be overwritten):
  677. if conf.libpath.isEmpty:
  678. # choose default libpath:
  679. var prefix = getPrefixDir(conf)
  680. conf.libpath = prefix / RelativeDir"lib"
  681. # Special rule to support other tools (nimble) which import the compiler
  682. # modules and make use of them.
  683. let realNimPath = findExe("nim")
  684. # Find out if $nim/../../lib/system.nim exists.
  685. let parentNimLibPath = realNimPath.parentDir.parentDir / "lib"
  686. if not fileExists(conf.libpath.string / "system.nim") and
  687. fileExists(parentNimLibPath / "system.nim"):
  688. conf.libpath = AbsoluteDir parentNimLibPath
  689. proc canonicalizePath*(conf: ConfigRef; path: AbsoluteFile): AbsoluteFile =
  690. result = AbsoluteFile path.string.expandFilename
  691. proc setFromProjectName*(conf: ConfigRef; projectName: string) =
  692. try:
  693. conf.projectFull = canonicalizePath(conf, AbsoluteFile projectName)
  694. except OSError:
  695. conf.projectFull = AbsoluteFile projectName
  696. let p = splitFile(conf.projectFull)
  697. let dir = if p.dir.isEmpty: AbsoluteDir getCurrentDir() else: p.dir
  698. try:
  699. conf.projectPath = AbsoluteDir canonicalizePath(conf, AbsoluteFile dir)
  700. except OSError:
  701. conf.projectPath = dir
  702. conf.projectName = p.name
  703. proc removeTrailingDirSep*(path: string): string =
  704. if (path.len > 0) and (path[^1] == DirSep):
  705. result = substr(path, 0, path.len - 2)
  706. else:
  707. result = path
  708. proc disableNimblePath*(conf: ConfigRef) =
  709. incl conf.globalOptions, optNoNimblePath
  710. conf.lazyPaths.setLen(0)
  711. conf.nimblePaths.setLen(0)
  712. proc clearNimblePath*(conf: ConfigRef) =
  713. conf.lazyPaths.setLen(0)
  714. conf.nimblePaths.setLen(0)
  715. include packagehandling
  716. proc getOsCacheDir(): string =
  717. when defined(posix):
  718. result = getEnv("XDG_CACHE_HOME", getHomeDir() / ".cache") / "nim"
  719. else:
  720. result = getHomeDir() / genSubDir.string
  721. proc getNimcacheDir*(conf: ConfigRef): AbsoluteDir =
  722. proc nimcacheSuffix(conf: ConfigRef): string =
  723. if conf.cmd == cmdCheck: "_check"
  724. elif isDefined(conf, "release") or isDefined(conf, "danger"): "_r"
  725. else: "_d"
  726. # XXX projectName should always be without a file extension!
  727. result =
  728. if not conf.nimcacheDir.isEmpty:
  729. conf.nimcacheDir
  730. elif conf.backend == backendJs:
  731. if conf.outDir.isEmpty:
  732. conf.projectPath / genSubDir
  733. else:
  734. conf.outDir / genSubDir
  735. else:
  736. AbsoluteDir(getOsCacheDir() / splitFile(conf.projectName).name &
  737. nimcacheSuffix(conf))
  738. proc pathSubs*(conf: ConfigRef; p, config: string): string =
  739. let home = removeTrailingDirSep(os.getHomeDir())
  740. result = unixToNativePath(p % [
  741. "nim", getPrefixDir(conf).string,
  742. "lib", conf.libpath.string,
  743. "home", home,
  744. "config", config,
  745. "projectname", conf.projectName,
  746. "projectpath", conf.projectPath.string,
  747. "projectdir", conf.projectPath.string,
  748. "nimcache", getNimcacheDir(conf).string]).expandTilde
  749. iterator nimbleSubs*(conf: ConfigRef; p: string): string =
  750. let pl = p.toLowerAscii
  751. if "$nimblepath" in pl or "$nimbledir" in pl:
  752. for i in countdown(conf.nimblePaths.len-1, 0):
  753. let nimblePath = removeTrailingDirSep(conf.nimblePaths[i].string)
  754. yield p % ["nimblepath", nimblePath, "nimbledir", nimblePath]
  755. else:
  756. yield p
  757. proc toGeneratedFile*(conf: ConfigRef; path: AbsoluteFile,
  758. ext: string): AbsoluteFile =
  759. ## converts "/home/a/mymodule.nim", "rod" to "/home/a/nimcache/mymodule.rod"
  760. result = getNimcacheDir(conf) / RelativeFile path.string.splitPath.tail.changeFileExt(ext)
  761. proc completeGeneratedFilePath*(conf: ConfigRef; f: AbsoluteFile,
  762. createSubDir: bool = true): AbsoluteFile =
  763. ## Return an absolute path of a generated intermediary file.
  764. ## Optionally creates the cache directory if `createSubDir` is `true`.
  765. let subdir = getNimcacheDir(conf)
  766. if createSubDir:
  767. try:
  768. createDir(subdir.string)
  769. except OSError:
  770. conf.quitOrRaise "cannot create directory: " & subdir.string
  771. result = subdir / RelativeFile f.string.splitPath.tail
  772. proc rawFindFile(conf: ConfigRef; f: RelativeFile; suppressStdlib: bool): AbsoluteFile =
  773. for it in conf.searchPaths:
  774. if suppressStdlib and it.string.startsWith(conf.libpath.string):
  775. continue
  776. result = it / f
  777. if fileExists(result):
  778. return canonicalizePath(conf, result)
  779. result = AbsoluteFile""
  780. proc rawFindFile2(conf: ConfigRef; f: RelativeFile): AbsoluteFile =
  781. for i, it in conf.lazyPaths:
  782. result = it / f
  783. if fileExists(result):
  784. # bring to front
  785. for j in countdown(i, 1):
  786. swap(conf.lazyPaths[j], conf.lazyPaths[j-1])
  787. return canonicalizePath(conf, result)
  788. result = AbsoluteFile""
  789. template patchModule(conf: ConfigRef) {.dirty.} =
  790. if not result.isEmpty and conf.moduleOverrides.len > 0:
  791. let key = getPackageName(conf, result.string) & "_" & splitFile(result).name
  792. if conf.moduleOverrides.hasKey(key):
  793. let ov = conf.moduleOverrides[key]
  794. if ov.len > 0: result = AbsoluteFile(ov)
  795. const stdlibDirs* = [
  796. "pure", "core", "arch",
  797. "pure/collections",
  798. "pure/concurrency",
  799. "pure/unidecode", "impure",
  800. "wrappers", "wrappers/linenoise",
  801. "windows", "posix", "js",
  802. "deprecated/pure"]
  803. const
  804. pkgPrefix = "pkg/"
  805. stdPrefix* = "std/"
  806. proc getRelativePathFromConfigPath*(conf: ConfigRef; f: AbsoluteFile, isTitle = false): RelativeFile =
  807. result = RelativeFile("")
  808. let f = $f
  809. if isTitle:
  810. for dir in stdlibDirs:
  811. let path = conf.libpath.string / dir / f.lastPathPart
  812. if path.cmpPaths(f) == 0:
  813. return RelativeFile(stdPrefix & f.splitFile.name)
  814. template search(paths) =
  815. for it in paths:
  816. let it = $it
  817. if f.isRelativeTo(it):
  818. return relativePath(f, it).RelativeFile
  819. search(conf.searchPaths)
  820. search(conf.lazyPaths)
  821. proc findFile*(conf: ConfigRef; f: string; suppressStdlib = false): AbsoluteFile =
  822. if f.isAbsolute:
  823. result = if f.fileExists: AbsoluteFile(f) else: AbsoluteFile""
  824. else:
  825. result = rawFindFile(conf, RelativeFile f, suppressStdlib)
  826. if result.isEmpty:
  827. result = rawFindFile(conf, RelativeFile f.toLowerAscii, suppressStdlib)
  828. if result.isEmpty:
  829. result = rawFindFile2(conf, RelativeFile f)
  830. if result.isEmpty:
  831. result = rawFindFile2(conf, RelativeFile f.toLowerAscii)
  832. patchModule(conf)
  833. proc findModule*(conf: ConfigRef; modulename, currentModule: string): AbsoluteFile =
  834. # returns path to module
  835. var m = addFileExt(modulename, NimExt)
  836. var hasRelativeDot = false
  837. if m.startsWith(pkgPrefix):
  838. result = findFile(conf, m.substr(pkgPrefix.len), suppressStdlib = true)
  839. else:
  840. if m.startsWith(stdPrefix):
  841. result = AbsoluteFile("")
  842. let stripped = m.substr(stdPrefix.len)
  843. for candidate in stdlibDirs:
  844. let path = (conf.libpath.string / candidate / stripped)
  845. if fileExists(path):
  846. result = AbsoluteFile path
  847. break
  848. else: # If prefixed with std/ why would we add the current module path!
  849. let currentPath = currentModule.splitFile.dir
  850. result = AbsoluteFile currentPath / m
  851. if m.startsWith('.') and not fileExists(result):
  852. result = AbsoluteFile ""
  853. hasRelativeDot = true
  854. if not fileExists(result) and not hasRelativeDot:
  855. result = findFile(conf, m)
  856. patchModule(conf)
  857. proc findProjectNimFile*(conf: ConfigRef; pkg: string): string =
  858. const extensions = [".nims", ".cfg", ".nimcfg", ".nimble"]
  859. var
  860. candidates: seq[string] = @[]
  861. dir = pkg
  862. prev = dir
  863. nimblepkg = ""
  864. let pkgname = pkg.lastPathPart()
  865. while true:
  866. for k, f in os.walkDir(dir, relative = true):
  867. if k == pcFile and f != "config.nims":
  868. let (_, name, ext) = splitFile(f)
  869. if ext in extensions:
  870. let x = changeFileExt(dir / name, ".nim")
  871. if fileExists(x):
  872. candidates.add x
  873. if ext == ".nimble":
  874. if nimblepkg.len == 0:
  875. nimblepkg = name
  876. # Since nimble packages can have their source in a subfolder,
  877. # check the last folder we were in for a possible match.
  878. if dir != prev:
  879. let x = prev / x.extractFilename()
  880. if fileExists(x):
  881. candidates.add x
  882. else:
  883. # If we found more than one nimble file, chances are that we
  884. # missed the real project file, or this is an invalid nimble
  885. # package. Either way, bailing is the better choice.
  886. return ""
  887. let pkgname = if nimblepkg.len > 0: nimblepkg else: pkgname
  888. for c in candidates:
  889. if pkgname in c.extractFilename(): return c
  890. if candidates.len > 0:
  891. return candidates[0]
  892. prev = dir
  893. dir = parentDir(dir)
  894. if dir == "": break
  895. return ""
  896. proc canonicalImportAux*(conf: ConfigRef, file: AbsoluteFile): string =
  897. ##[
  898. Shows the canonical module import, e.g.:
  899. system, std/tables, fusion/pointers, system/assertions, std/private/asciitables
  900. ]##
  901. var ret = getRelativePathFromConfigPath(conf, file, isTitle = true)
  902. let dir = getNimbleFile(conf, $file).parentDir.AbsoluteDir
  903. if not dir.isEmpty:
  904. let relPath = relativeTo(file, dir)
  905. if not relPath.isEmpty and (ret.isEmpty or relPath.string.len < ret.string.len):
  906. ret = relPath
  907. if ret.isEmpty:
  908. ret = relativeTo(file, conf.projectPath)
  909. result = ret.string
  910. proc canonicalImport*(conf: ConfigRef, file: AbsoluteFile): string =
  911. let ret = canonicalImportAux(conf, file)
  912. result = ret.nativeToUnixPath.changeFileExt("")
  913. proc canonDynlibName(s: string): string =
  914. let start = if s.startsWith("lib"): 3 else: 0
  915. let ende = strutils.find(s, {'(', ')', '.'})
  916. if ende >= 0:
  917. result = s.substr(start, ende-1)
  918. else:
  919. result = s.substr(start)
  920. proc inclDynlibOverride*(conf: ConfigRef; lib: string) =
  921. conf.dllOverrides[lib.canonDynlibName] = "true"
  922. proc isDynlibOverride*(conf: ConfigRef; lib: string): bool =
  923. result = optDynlibOverrideAll in conf.globalOptions or
  924. conf.dllOverrides.hasKey(lib.canonDynlibName)
  925. proc showNonExportedFields*(conf: ConfigRef) =
  926. incl(conf.globalOptions, optShowNonExportedFields)
  927. proc expandDone*(conf: ConfigRef): bool =
  928. result = conf.ideCmd == ideExpand and conf.expandLevels == 0 and conf.expandProgress
  929. proc parseIdeCmd*(s: string): IdeCmd =
  930. case s:
  931. of "sug": ideSug
  932. of "con": ideCon
  933. of "def": ideDef
  934. of "use": ideUse
  935. of "dus": ideDus
  936. of "chk": ideChk
  937. of "chkFile": ideChkFile
  938. of "mod": ideMod
  939. of "highlight": ideHighlight
  940. of "outline": ideOutline
  941. of "known": ideKnown
  942. of "msg": ideMsg
  943. of "project": ideProject
  944. of "globalSymbols": ideGlobalSymbols
  945. of "recompile": ideRecompile
  946. of "changed": ideChanged
  947. of "type": ideType
  948. else: ideNone
  949. proc `$`*(c: IdeCmd): string =
  950. case c:
  951. of ideSug: "sug"
  952. of ideCon: "con"
  953. of ideDef: "def"
  954. of ideUse: "use"
  955. of ideDus: "dus"
  956. of ideChk: "chk"
  957. of ideChkFile: "chkFile"
  958. of ideMod: "mod"
  959. of ideNone: "none"
  960. of ideHighlight: "highlight"
  961. of ideOutline: "outline"
  962. of ideKnown: "known"
  963. of ideMsg: "msg"
  964. of ideProject: "project"
  965. of ideGlobalSymbols: "globalSymbols"
  966. of ideDeclaration: "declaration"
  967. of ideExpand: "expand"
  968. of ideRecompile: "recompile"
  969. of ideChanged: "changed"
  970. of ideType: "type"
  971. of ideInlayHints: "inlayHints"
  972. proc floatInt64Align*(conf: ConfigRef): int16 =
  973. ## Returns either 4 or 8 depending on reasons.
  974. if conf != nil and conf.target.targetCPU == cpuI386:
  975. #on Linux/BSD i386, double are aligned to 4bytes (except with -malign-double)
  976. if conf.target.targetOS != osWindows:
  977. # on i386 for all known POSIX systems, 64bits ints are aligned
  978. # to 4bytes (except with -malign-double)
  979. return 4
  980. return 8