options.nim 40 KB

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