options.nim 40 KB

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