1 -----------------------------------------------------------------------------
5 -- Static flags can only be set once, on the command-line. Inside GHC,
6 -- each static flag corresponds to a top-level value, usually of type Bool.
8 -- (c) The University of Glasgow 2005
10 -----------------------------------------------------------------------------
12 module StaticFlagParser (parseStaticFlags) where
14 #include "HsVersions.h"
27 -----------------------------------------------------------------------------
30 parseStaticFlags :: [String] -> IO ([String], [String])
31 parseStaticFlags args = do
32 ready <- readIORef v_opt_C_ready
33 when ready $ ghcError (ProgramError "Too late for parseStaticFlags: call it before newSession")
35 (leftover, errs, warns1) <- processArgs static_flags args
36 when (not (null errs)) $ ghcError (UsageError (unlines errs))
38 -- deal with the way flags: the way (eg. prof) gives rise to
39 -- further flags, some of which might be static.
40 way_flags <- findBuildTag
42 -- if we're unregisterised, add some more flags
43 let unreg_flags | cGhcUnregisterised == "YES" = unregFlags
46 (more_leftover, errs, warns2) <- processArgs static_flags (unreg_flags ++ way_flags)
48 -- see sanity code in staticOpts
49 writeIORef v_opt_C_ready True
51 -- TABLES_NEXT_TO_CODE affects the info table layout.
52 -- Be careful to do this *after* all processArgs,
53 -- because evaluating tablesNextToCode involves looking at the global
54 -- static flags. Those pesky global variables...
55 let cg_flags | tablesNextToCode = ["-optc-DTABLES_NEXT_TO_CODE"]
58 -- HACK: -fexcess-precision is both a static and a dynamic flag. If
59 -- the static flag parser has slurped it, we must return it as a
60 -- leftover too. ToDo: make -fexcess-precision dynamic only.
61 let excess_prec | opt_SimplExcessPrecision = ["-fexcess-precision"]
64 when (not (null errs)) $ ghcError (UsageError (unlines errs))
65 return (excess_prec ++ cg_flags ++ more_leftover ++ leftover,
68 static_flags :: [Flag IO]
69 -- All the static flags should appear in this list. It describes how each
70 -- static flag should be processed. Two main purposes:
71 -- (a) if a command-line flag doesn't appear in the list, GHC can complain
72 -- (b) a command-line flag may remove, or add, other flags; e.g. the "-fno-X" things
74 -- The common (PassFlag addOpt) action puts the static flag into the bunch of
75 -- things that are searched up by the top-level definitions like
76 -- opt_foo = lookUp (fsLit "-dfoo")
78 -- Note that ordering is important in the following list: any flag which
79 -- is a prefix flag (i.e. HasArg, Prefix, OptPrefix, AnySuffix) will override
80 -- flags further down the list with the same prefix.
83 ------- GHCi -------------------------------------------------------
84 Flag "ignore-dot-ghci" (PassFlag addOpt) Supported
85 , Flag "read-dot-ghci" (NoArg (removeOpt "-ignore-dot-ghci")) Supported
87 ------- ways --------------------------------------------------------
88 , Flag "prof" (NoArg (addWay WayProf)) Supported
89 , Flag "ticky" (NoArg (addWay WayTicky)) Supported
90 , Flag "parallel" (NoArg (addWay WayPar)) Supported
91 , Flag "gransim" (NoArg (addWay WayGran)) Supported
92 , Flag "smp" (NoArg (addWay WayThreaded))
93 (Deprecated "Use -threaded instead")
94 , Flag "debug" (NoArg (addWay WayDebug)) Supported
95 , Flag "ndp" (NoArg (addWay WayNDP)) Supported
96 , Flag "threaded" (NoArg (addWay WayThreaded)) Supported
99 ------ Debugging ----------------------------------------------------
100 , Flag "dppr-debug" (PassFlag addOpt) Supported
101 , Flag "dsuppress-uniques" (PassFlag addOpt) Supported
102 , Flag "dppr-user-length" (AnySuffix addOpt) Supported
103 , Flag "dopt-fuel" (AnySuffix addOpt) Supported
104 , Flag "dno-debug-output" (PassFlag addOpt) Supported
105 -- rest of the debugging flags are dynamic
107 --------- Profiling --------------------------------------------------
108 , Flag "auto-all" (NoArg (addOpt "-fauto-sccs-on-all-toplevs"))
110 , Flag "auto" (NoArg (addOpt "-fauto-sccs-on-exported-toplevs"))
112 , Flag "caf-all" (NoArg (addOpt "-fauto-sccs-on-individual-cafs"))
114 -- "ignore-sccs" doesn't work (ToDo)
116 , Flag "no-auto-all" (NoArg (removeOpt "-fauto-sccs-on-all-toplevs"))
118 , Flag "no-auto" (NoArg (removeOpt "-fauto-sccs-on-exported-toplevs"))
120 , Flag "no-caf-all" (NoArg (removeOpt "-fauto-sccs-on-individual-cafs"))
123 ----- Linker --------------------------------------------------------
124 , Flag "static" (PassFlag addOpt) Supported
125 , Flag "dynamic" (NoArg (removeOpt "-static")) Supported
126 -- ignored for compat w/ gcc:
127 , Flag "rdynamic" (NoArg (return ())) Supported
129 ----- RTS opts ------------------------------------------------------
130 , Flag "H" (HasArg (setHeapSize . fromIntegral . decodeSize))
132 , Flag "Rghc-timing" (NoArg (enableTimingStats)) Supported
134 ------ Compiler flags -----------------------------------------------
135 -- All other "-fno-<blah>" options cancel out "-f<blah>" on the hsc cmdline
137 (PrefixPred (\s -> isStaticFlag ("f"++s)) (\s -> removeOpt ("-f"++s)))
140 -- Pass all remaining "-f<blah>" options to hsc
141 , Flag "f" (AnySuffixPred (isStaticFlag) addOpt)
145 isStaticFlag :: String -> Bool
148 "fauto-sccs-on-all-toplevs",
149 "fauto-sccs-on-exported-toplevs",
150 "fauto-sccs-on-individual-cafs",
153 "fspec-inline-join-points",
154 "firrefutable-tuples",
157 "fno-hi-version-check",
159 "fno-method-sharing",
161 "fno-ds-multi-tyvar",
166 "fhardwire-lib-paths",
174 || any (`isPrefixOf` f) [
175 "fliberate-case-threshold",
178 "funfolding-creation-threshold",
179 "funfolding-use-threshold",
180 "funfolding-fun-discount",
181 "funfolding-keeness-factor"
184 unregFlags :: [String]
187 , "-optc-DUSE_MINIINTERPRETER"
188 , "-fno-asm-mangling"
192 -----------------------------------------------------------------------------
193 -- convert sizes like "3.5M" into integers
195 decodeSize :: String -> Integer
197 | c == "" = truncate n
198 | c == "K" || c == "k" = truncate (n * 1000)
199 | c == "M" || c == "m" = truncate (n * 1000 * 1000)
200 | c == "G" || c == "g" = truncate (n * 1000 * 1000 * 1000)
201 | otherwise = ghcError (CmdLineError ("can't decode size: " ++ str))
202 where (m, c) = span pred str
204 pred c = isDigit c || c == '.'
206 -----------------------------------------------------------------------------
209 foreign import ccall unsafe "setHeapSize" setHeapSize :: Int -> IO ()
210 foreign import ccall unsafe "enableTimingStats" enableTimingStats :: IO ()