+ where
+ this_mod = mi_module iface0
+ dflags = hsc_dflags hsc_env
+ this_pkg = thisPackage dflags
+ (non_orph_insts, orph_insts) = mkOrphMap ifInstOrph (mi_insts iface0)
+ (non_orph_rules, orph_rules) = mkOrphMap ifRuleOrph (mi_rules iface0)
+ -- ToDo: shouldn't we be splitting fam_insts into orphans and
+ -- non-orphans?
+ fam_insts = mi_fam_insts iface0
+ fix_fn = mi_fix_fn iface0
+ pp_orphs = pprOrphans orph_insts orph_rules
+
+
+getOrphanHashes :: HscEnv -> [Module] -> IO [Fingerprint]
+getOrphanHashes hsc_env mods = do
+ eps <- hscEPS hsc_env
+ let
+ hpt = hsc_HPT hsc_env
+ pit = eps_PIT eps
+ dflags = hsc_dflags hsc_env
+ get_orph_hash mod =
+ case lookupIfaceByModule dflags hpt pit mod of
+ Nothing -> pprPanic "moduleOrphanHash" (ppr mod)
+ Just iface -> mi_orphan_hash iface
+ --
+ return (map get_orph_hash mods)
+
+
+sortDependencies :: Dependencies -> Dependencies
+sortDependencies d
+ = Deps { dep_mods = sortBy (compare `on` (moduleNameFS.fst)) (dep_mods d),
+ dep_pkgs = sortBy (compare `on` packageIdFS) (dep_pkgs d),
+ dep_orphs = sortBy stableModuleCmp (dep_orphs d),
+ dep_finsts = sortBy stableModuleCmp (dep_finsts d) }
+
+-- The ABI of a declaration consists of:
+ -- the full name of the identifier (inc. module and package, because
+ -- these are used to construct the symbol name by which the
+ -- identifier is known externally).
+ -- the fixity of the identifier
+ -- the declaration itself, as exposed to clients. That is, the
+ -- definition of an Id is included in the fingerprint only if
+ -- it is made available as as unfolding in the interface.
+ -- for Ids: rules
+ -- for classes: instances, fixity & rules for methods
+ -- for datatypes: instances, fixity & rules for constrs
+type IfaceDeclABI = (Module, IfaceDecl, IfaceDeclExtras)
+
+abiDecl :: IfaceDeclABI -> IfaceDecl
+abiDecl (_, decl, _) = decl
+
+cmp_abiNames :: IfaceDeclABI -> IfaceDeclABI -> Ordering
+cmp_abiNames abi1 abi2 = ifName (abiDecl abi1) `compare`
+ ifName (abiDecl abi2)
+
+freeNamesDeclABI :: IfaceDeclABI -> NameSet
+freeNamesDeclABI (_mod, decl, extras) =
+ freeNamesIfDecl decl `unionNameSets` freeNamesDeclExtras extras
+
+data IfaceDeclExtras
+ = IfaceIdExtras Fixity [IfaceRule]
+ | IfaceDataExtras Fixity [IfaceInstABI] [(Fixity,[IfaceRule])]
+ | IfaceClassExtras [IfaceInstABI] [(Fixity,[IfaceRule])]
+ | IfaceOtherDeclExtras
+
+freeNamesDeclExtras :: IfaceDeclExtras -> NameSet
+freeNamesDeclExtras (IfaceIdExtras _ rules)
+ = unionManyNameSets (map freeNamesIfRule rules)
+freeNamesDeclExtras (IfaceDataExtras _ _insts subs)
+ = unionManyNameSets (map freeNamesSub subs)
+freeNamesDeclExtras (IfaceClassExtras _insts subs)
+ = unionManyNameSets (map freeNamesSub subs)
+freeNamesDeclExtras IfaceOtherDeclExtras
+ = emptyNameSet
+
+freeNamesSub :: (Fixity,[IfaceRule]) -> NameSet
+freeNamesSub (_,rules) = unionManyNameSets (map freeNamesIfRule rules)
+
+instance Binary IfaceDeclExtras where
+ get _bh = panic "no get for IfaceDeclExtras"
+ put_ bh (IfaceIdExtras fix rules) = do
+ putByte bh 1; put_ bh fix; put_ bh rules
+ put_ bh (IfaceDataExtras fix insts cons) = do
+ putByte bh 2; put_ bh fix; put_ bh insts; put_ bh cons
+ put_ bh (IfaceClassExtras insts methods) = do
+ putByte bh 3; put_ bh insts; put_ bh methods
+ put_ bh IfaceOtherDeclExtras = do
+ putByte bh 4
+
+declExtras :: (OccName -> Fixity)
+ -> OccEnv [IfaceRule]
+ -> OccEnv [IfaceInst]
+ -> IfaceDecl
+ -> IfaceDeclExtras
+
+declExtras fix_fn rule_env inst_env decl
+ = case decl of
+ IfaceId{} -> IfaceIdExtras (fix_fn n)
+ (lookupOccEnvL rule_env n)
+ IfaceData{ifCons=cons} ->
+ IfaceDataExtras (fix_fn n)
+ (map IfaceInstABI $ lookupOccEnvL inst_env n)
+ (map (id_extras . ifConOcc) (visibleIfConDecls cons))
+ IfaceClass{ifSigs=sigs} ->
+ IfaceClassExtras
+ (map IfaceInstABI $ lookupOccEnvL inst_env n)
+ [id_extras op | IfaceClassOp op _ _ <- sigs]
+ _other -> IfaceOtherDeclExtras
+ where
+ n = ifName decl
+ id_extras occ = (fix_fn occ, lookupOccEnvL rule_env occ)
+
+--
+-- When hashing an instance, we hash only its structure, not the
+-- fingerprints of the things it mentions. See the section on instances
+-- in the commentary,
+-- http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/RecompilationAvoidance
+--
+newtype IfaceInstABI = IfaceInstABI IfaceInst
+
+instance Binary IfaceInstABI where
+ get = panic "no get for IfaceInstABI"
+ put_ bh (IfaceInstABI inst) = do
+ let ud = getUserData bh
+ bh' = setUserData bh (ud{ ud_put_name = putNameLiterally })
+ put_ bh' inst
+
+lookupOccEnvL :: OccEnv [v] -> OccName -> [v]
+lookupOccEnvL env k = lookupOccEnv env k `orElse` []
+
+-- used when we want to fingerprint a structure without depending on the
+-- fingerprints of external Names that it refers to.
+putNameLiterally :: BinHandle -> Name -> IO ()
+putNameLiterally bh name = do
+ put_ bh $! nameModule name
+ put_ bh $! nameOccName name
+
+computeFingerprint :: Binary a
+ => DynFlags
+ -> (BinHandle -> Name -> IO ())
+ -> a
+ -> IO Fingerprint
+
+computeFingerprint _dflags put_name a = do
+ bh <- openBinMem (3*1024) -- just less than a block
+ ud <- newWriteState put_name putFS
+ bh <- return $ setUserData bh ud
+ put_ bh a
+ fingerprintBinMem bh
+
+{-
+-- for testing: use the md5sum command to generate fingerprints and
+-- compare the results against our built-in version.
+ fp' <- oldMD5 dflags bh
+ if fp /= fp' then pprPanic "computeFingerprint" (ppr fp <+> ppr fp')
+ else return fp
+
+oldMD5 dflags bh = do
+ tmp <- newTempName dflags "bin"
+ writeBinMem bh tmp
+ tmp2 <- newTempName dflags "md5"
+ let cmd = "md5sum " ++ tmp ++ " >" ++ tmp2
+ r <- system cmd
+ case r of
+ ExitFailure _ -> ghcError (PhaseFailed cmd r)
+ ExitSuccess -> do
+ hash_str <- readFile tmp2
+ return $! readHexFingerprint hash_str
+-}
+
+pprOrphans :: [IfaceInst] -> [IfaceRule] -> Maybe SDoc