module StaticFlagParser (parseStaticFlags) where
#include "HsVersions.h"
import qualified StaticFlags as SF
import StaticFlags ( v_opt_C_ready, getWayFlags, tablesNextToCode, WayName(..)
, opt_SimplExcessPrecision )
import CmdLineParser
import Config
import SrcLoc
import Util
import Panic
import Control.Monad
import Data.Char
import Data.IORef
import Data.List
parseStaticFlags :: [Located String] -> IO ([Located String], [Located String])
parseStaticFlags args = do
ready <- readIORef v_opt_C_ready
when ready $ ghcError (ProgramError "Too late for parseStaticFlags: call it before newSession")
(leftover, errs, warns1) <- processArgs static_flags args CmdLineOnly True
when (not (null errs)) $ ghcError $ errorsToGhcException errs
way_flags <- getWayFlags
let way_flags' = map (mkGeneralLocated "in way flags") way_flags
let unreg_flags | cGhcUnregisterised == "YES" = unregFlags
| otherwise = []
(more_leftover, errs, warns2) <-
processArgs static_flags (unreg_flags ++ way_flags') CmdLineOnly True
writeIORef v_opt_C_ready True
let cg_flags | tablesNextToCode = map (mkGeneralLocated "in cg_flags")
["-optc-DTABLES_NEXT_TO_CODE"]
| otherwise = []
let excess_prec
| opt_SimplExcessPrecision = map (mkGeneralLocated "in excess_prec")
["-fexcess-precision"]
| otherwise = []
when (not (null errs)) $ ghcError $ errorsToGhcException errs
return (excess_prec ++ cg_flags ++ more_leftover ++ leftover,
warns1 ++ warns2)
static_flags :: [Flag IO]
static_flags = [
flagC "ignore-dot-ghci" (PassFlag addOpt)
, flagC "read-dot-ghci" (NoArg (removeOpt "-ignore-dot-ghci"))
, flagC "prof" (NoArg (addWay WayProf))
, flagC "eventlog" (NoArg (addWay WayEventLog))
, flagC "parallel" (NoArg (addWay WayPar))
, flagC "gransim" (NoArg (addWay WayGran))
, flagC "smp" (NoArg (addWay WayThreaded >> deprecate "Use -threaded instead"))
, flagC "debug" (NoArg (addWay WayDebug))
, flagC "ndp" (NoArg (addWay WayNDP))
, flagC "threaded" (NoArg (addWay WayThreaded))
, flagC "ticky" (PassFlag (\f -> do addOpt f; addWay WayDebug))
, flagC "dppr-debug" (PassFlag addOpt)
, flagC "dppr-cols" (AnySuffix addOpt)
, flagC "dppr-user-length" (AnySuffix addOpt)
, flagC "dppr-case-as-let" (PassFlag addOpt)
, flagC "dsuppress-all" (PassFlag addOpt)
, flagC "dsuppress-uniques" (PassFlag addOpt)
, flagC "dsuppress-coercions" (PassFlag addOpt)
, flagC "dsuppress-module-prefixes" (PassFlag addOpt)
, flagC "dsuppress-type-applications" (PassFlag addOpt)
, flagC "dsuppress-idinfo" (PassFlag addOpt)
, flagC "dsuppress-type-signatures" (PassFlag addOpt)
, flagC "dopt-fuel" (AnySuffix addOpt)
, flagC "dtrace-level" (AnySuffix addOpt)
, flagC "dno-debug-output" (PassFlag addOpt)
, flagC "dstub-dead-values" (PassFlag addOpt)
, flagC "static" (PassFlag addOpt)
, flagC "dynamic" (NoArg (removeOpt "-static" >> addWay WayDyn))
, flagC "rdynamic" (NoArg (return ()))
, flagC "H" (HasArg (\s -> liftEwM (setHeapSize (fromIntegral (decodeSize s)))))
, flagC "Rghc-timing" (NoArg (liftEwM enableTimingStats))
, flagC "fPIC" (PassFlag setPIC)
, flagC "fno-"
(PrefixPred (\s -> isStaticFlag ("f"++s)) (\s -> removeOpt ("-f"++s)))
, flagC "f" (AnySuffixPred isStaticFlag addOpt)
]
setPIC :: String -> StaticP ()
setPIC | cGhcWithNativeCodeGen == "YES" || cGhcUnregisterised == "YES"
= addOpt
| otherwise
= ghcError $ CmdLineError "-fPIC is not supported on this platform"
isStaticFlag :: String -> Bool
isStaticFlag f =
f `elem` [
"fscc-profiling",
"fdicts-strict",
"fspec-inline-join-points",
"firrefutable-tuples",
"fparallel",
"fgransim",
"fno-hi-version-check",
"dno-black-holing",
"fno-state-hack",
"fsimple-list-literals",
"fruntime-types",
"fno-pre-inlining",
"fno-opt-coercion",
"fexcess-precision",
"static",
"fhardwire-lib-paths",
"funregisterised",
"fcpr-off",
"ferror-spans",
"fPIC",
"fhpc"
]
|| any (`isPrefixOf` f) [
"fliberate-case-threshold",
"fmax-worker-args",
"fhistory-size",
"funfolding-creation-threshold",
"funfolding-dict-threshold",
"funfolding-use-threshold",
"funfolding-fun-discount",
"funfolding-keeness-factor"
]
unregFlags :: [Located String]
unregFlags = map (mkGeneralLocated "in unregFlags")
[ "-optc-DNO_REGS"
, "-optc-DUSE_MINIINTERPRETER"
, "-funregisterised" ]
decodeSize :: String -> Integer
decodeSize str
| c == "" = truncate n
| c == "K" || c == "k" = truncate (n * 1000)
| c == "M" || c == "m" = truncate (n * 1000 * 1000)
| c == "G" || c == "g" = truncate (n * 1000 * 1000 * 1000)
| otherwise = ghcError (CmdLineError ("can't decode size: " ++ str))
where (m, c) = span pred str
n = readRational m
pred c = isDigit c || c == '.'
type StaticP = EwM IO
addOpt :: String -> StaticP ()
addOpt = liftEwM . SF.addOpt
addWay :: WayName -> StaticP ()
addWay = liftEwM . SF.addWay
removeOpt :: String -> StaticP ()
removeOpt = liftEwM . SF.removeOpt
foreign import ccall unsafe "setHeapSize" setHeapSize :: Int -> IO ()
foreign import ccall unsafe "enableTimingStats" enableTimingStats :: IO ()