import CmdLineOpts
import Id ( Id, idType, idInfo, omitIfaceSigForId, isUserExportedId,
- getIdSpecialisation
+ idSpecialisation
)
import Var ( isId )
import VarSet
cafInfo, ppCafInfo, specInfo,
cprInfo, ppCprInfo, pprInlinePragInfo,
occInfo, OccInfo(..),
- workerExists, workerInfo, ppWorkerInfo
+ workerExists, workerInfo, ppWorkerInfo, WorkerInfo(..)
)
import CoreSyn ( CoreExpr, CoreBind, Bind(..), rulesRules, rulesRhsFreeVars )
import CoreFVs ( exprSomeFreeVars, ruleSomeLhsFreeVars, ruleSomeFreeVars )
-import CoreUnfold ( calcUnfoldingGuidance, okToUnfoldInHiFile, couldBeSmallEnoughToInline )
+import CoreUnfold ( okToUnfoldInHiFile, couldBeSmallEnoughToInline )
import Module ( moduleString, pprModule, pprModuleName )
import Name ( isLocallyDefined, isWiredInName, nameRdrName, nameModule,
Name, NamedThing(..)
@ifaceExportList@ produces the @__exports__@ section; it appends
to the handle provided by @startIface@.
+NOTE: ALWAYS remember that ghc-iface.lprl rewrites the interface file,
+so you have to keep it in synch with the code below. Otherwise you'll
+lose the happiest years of your life, believe me... -- SUP
+
\begin{code}
startIface :: Module -> InterfaceDetails
-> IO (Maybe Handle) -- Nothing <=> don't do an interface
-> [Id] -- Ids used at code-gen time; they have better pragma info!
-> [CoreBind] -- In dependency order, later depend on earlier
-> [ProtoCoreRule] -- Rules
+ -> [Deprecation Name]
-> IO ()
endIface :: Maybe Handle -> IO ()
\end{code}
\begin{code}
-startIface mod (has_orphans, import_usages, ExportEnv avails fixities _)
+startIface mod (InterfaceDetails has_orphans import_usages (ExportEnv avails fixities _) _)
= case opt_ProduceHi of
Nothing -> return Nothing ; -- not producing any .hi file
\begin{code}
-ifaceDecls Nothing tycons classes inst_info final_ids simplified rules = return ()
+ifaceDecls Nothing tycons classes inst_info final_ids simplified rules _ = return ()
ifaceDecls (Just hdl)
tycons classes
inst_infos
- final_ids binds
+ final_ids
+ binds
orphan_rules -- Rules defined locally for an Id that is *not* defined locally
+ deprecations
| null_decls = return ()
-- You could have a module with just (re-)exports/instances in it
| otherwise
ifaceBinds hdl (inst_ids `unionVarSet` orphan_rule_ids)
final_ids binds >>= \ emitted_ids ->
ifaceRules hdl orphan_rules emitted_ids >>
- return ()
+ ifaceDeprecations hdl deprecations
where
orphan_rule_ids = unionVarSets [ ruleSomeFreeVars interestingId rule
| ProtoCoreRule _ _ rule <- orphan_rules]
- null_decls = null binds &&
- null tycons &&
- null classes &&
- isEmptyBag inst_infos &&
- null orphan_rules
+ null_decls = null binds &&
+ null tycons &&
+ null classes &&
+ isEmptyBag inst_infos &&
+ null orphan_rules &&
+ null deprecations
\end{code}
\begin{code}
+ifaceImports :: Handle -> VersionInfo Name -> IO ()
ifaceImports if_hdl import_usages
= hPutCol if_hdl upp_uses (sortLt lt_imp_vers import_usages)
where
- upp_uses (m, mv, has_orphans, whats_imported)
+ upp_uses (m, mv, has_orphans, is_boot, whats_imported)
= hsep [ptext SLIT("import"), pprModuleName m,
- int mv, pp_orphan,
+ int mv, pp_orphan, pp_boot,
upp_import_versions whats_imported
] <> semi
where
pp_orphan | has_orphans = ptext SLIT("!")
| otherwise = empty
+ pp_boot | is_boot = ptext SLIT("@")
+ | otherwise = empty
-- Importing the whole module is indicated by an empty list
upp_import_versions Everything = empty
upp_import_versions (Specifically nvs)
= dcolon <+> hsep [ hsep [ppr_unqual_name n, int v] | (n,v) <- sort_versions nvs ]
+{- SUP: What's this??
ifaceModuleDeps if_hdl [] = return ()
ifaceModuleDeps if_hdl mod_deps
= let
in
printForIface if_hdl (ptext SLIT("__depends") <+> vcat lines <> ptext SLIT(" ;")) >>
hPutStr if_hdl "\n"
+-}
+ifaceExports :: Handle -> Avails -> IO ()
ifaceExports if_hdl [] = return ()
ifaceExports if_hdl avails
= hPutCol if_hdl do_one_module (fmToList export_fm)
hsep (map upp_avail (sortLt lt_avail avails))
] <> semi
+ifaceFixities :: Handle -> Fixities -> IO ()
ifaceFixities if_hdl [] = return ()
ifaceFixities if_hdl fixities
= hPutCol if_hdl upp_fixity fixities
+ifaceRules :: Handle -> [ProtoCoreRule] -> IdSet -> IO ()
ifaceRules if_hdl rules emitted
- | null orphan_rule_pretties && null local_id_pretties
+ | opt_OmitInterfacePragmas -- Don't emit rules if we are suppressing
+ -- interface pragmas
+ || (null orphan_rule_pretties && null local_id_pretties)
= return ()
| otherwise
- = do printForIface if_hdl (vcat [
+ = printForIface if_hdl (vcat [
ptext SLIT("{-## __R"),
-
vcat orphan_rule_pretties,
-
vcat local_id_pretties,
-
ptext SLIT("##-}")
- ])
-
- return ()
+ ])
where
orphan_rule_pretties = [ pprCoreRule (Just fn) rule
| ProtoCoreRule _ fn rule <- rules
]
local_id_pretties = [ pprCoreRule (Just fn) rule
| fn <- varSetElems emitted,
- rule <- rulesRules (getIdSpecialisation fn),
+ rule <- rulesRules (idSpecialisation fn),
all (`elemVarSet` emitted) (varSetElems (ruleSomeLhsFreeVars interestingId rule))
- -- Spit out a rule only if all its lhs free vars are eemitted
+ -- Spit out a rule only if all its lhs free vars are emitted
+ -- This is a good reason not to do it when we emit the Id itself
]
+
+ifaceDeprecations :: Handle -> [Deprecation Name] -> IO ()
+ifaceDeprecations if_hdl [] = return ()
+ifaceDeprecations if_hdl deprecations
+ = printForIface if_hdl (vcat [
+ ptext SLIT("{-## __D"),
+ vcat [ pprIE ie <+> doubleQuotes (ppr txt) <> semi | Deprecation ie txt <- deprecations ],
+ ptext SLIT("##-}")
+ ])
+ where
+ pprIE (IEVar n ) = ppr n
+ pprIE (IEThingAbs n ) = ppr n
+ pprIE (IEThingAll n ) = hcat [ppr n, text "(..)"]
+ pprIE (IEThingWith n ns) = ppr n <> parens (hcat (punctuate comma (map ppr ns)))
+ pprIE (IEModuleContents _ ) = empty
\end{code}
%************************************************************************
work_info = workerInfo core_idinfo
has_worker = workerExists work_info
wrkr_pretty = ppWorkerInfo work_info
- Just work_id = work_info
+ HasWorker work_id wrap_arity = work_info
------------ Occ info --------------
rhs_is_small && -- Small enough
okToUnfoldInHiFile rhs -- No casms etc
- rhs_is_small = couldBeSmallEnoughToInline (calcUnfoldingGuidance opt_UF_HiFileThreshold rhs)
+ rhs_is_small = couldBeSmallEnoughToInline opt_UF_HiFileThreshold rhs
------------ Specialisations --------------
spec_info = specInfo core_idinfo
------------ Sanity checking --------------
-- The arity of a wrapper function should match its strictness,
-- or else an importing module will get very confused indeed.
- -- [later: actually all that is necessary is for strictness to exceed arity]
- arity_matches_strictness
- = not has_worker ||
- case strict_info of
- StrictnessInfo ds _ -> length ds >= arityLowerBound arity_info
- other -> True
+ arity_matches_strictness = not has_worker ||
+ wrap_arity == arityLowerBound arity_info
interestingId id = isId id && isLocallyDefined id &&
not (omitIfaceSigForId id)
lt_lexical a1 a2 = getName a1 `lt_name` getName a2
lt_imp_vers :: ImportVersion a -> ImportVersion a -> Bool
-lt_imp_vers (m1,_,_,_) (m2,_,_,_) = m1 < m2
+lt_imp_vers (m1,_,_,_,_) (m2,_,_,_,_) = m1 < m2
sort_versions vs = sortLt lt_vers vs