[project @ 1999-07-08 13:46:25 by sof]
[ghc-hetmet.git] / ghc / compiler / rename / RnIfaces.lhs
index 8298af0..9683ef2 100644 (file)
@@ -13,7 +13,8 @@ module RnIfaces (
 
        checkUpToDate,
 
-       getDeclBinders, getDeclSysBinders
+       getDeclBinders, getDeclSysBinders,
+       removeContext           -- removeContext probably belongs somewhere else
     ) where
 
 #include "HsVersions.h"
@@ -21,6 +22,7 @@ module RnIfaces (
 import CmdLineOpts     ( opt_NoPruneDecls, opt_IgnoreIfacePragmas )
 import HsSyn           ( HsDecl(..), TyClDecl(..), InstDecl(..), IfaceSig(..), 
                          HsType(..), ConDecl(..), IE(..), ConDetails(..), Sig(..),
+                         ForeignDecl(..), ForKind(..), isDynamic,
                          FixitySig(..), RuleDecl(..),
                          isClassOpSig
                        )
@@ -29,7 +31,7 @@ import RdrHsSyn               ( RdrNameHsDecl, RdrNameInstDecl, RdrNameTyClDecl, RdrNameRuleD
                          extractHsTyRdrNames
                        )
 import RnEnv           ( mkImportedGlobalName, newImportedBinder, mkImportedGlobalFromRdrName,
-                         lookupOccRn,
+                         lookupOccRn, lookupImplicitOccRn,
                          pprAvail,
                          availName, availNames, addAvailToNameSet,
                          FreeVars, emptyFVs
@@ -79,9 +81,19 @@ import List  ( nub )
 %*********************************************************
 
 \begin{code}
-loadHomeInterface :: SDoc -> Name -> RnM d (Module, Ifaces)
+loadHomeInterface :: SDoc -> Name -> RnM d Ifaces
 loadHomeInterface doc_str name
-  = loadInterface doc_str (moduleName (nameModule name)) ImportBySystem
+  = loadInterface doc_str (moduleName (nameModule name)) ImportBySystem                `thenRn` \ (_, ifaces) ->
+    returnRn ifaces
+
+loadOrphanModules :: [ModuleName] -> RnM d ()
+loadOrphanModules mods
+  | null mods = returnRn ()
+  | otherwise = traceRn (text "Loading orphan modules:" <+> fsep (map pprModuleName mods))     `thenRn_` 
+               mapRn_ load mods        `thenRn_`
+               returnRn ()
+  where
+    load mod = loadInterface (pprModuleName mod <+> ptext SLIT("is a orphan-instance module")) mod ImportBySystem
 
 loadInterface :: SDoc -> ModuleName -> WhereFrom -> RnM d (Module, Ifaces)
 loadInterface doc_str mod_name from
@@ -444,13 +456,9 @@ importDecl name
     if name `elemNameSet` already_slurped then
        returnRn Nothing        -- Already dealt with
     else
-       getModuleRn             `thenRn` \ this_mod ->
-       let
-         mod = moduleName (nameModule name)
-       in
-       if mod == this_mod then         -- Don't bring in decls from
+       if isLocallyDefined name then   -- Don't bring in decls from
                                        -- the renamed module's own interface file
-                 addWarnRn (importDeclWarn mod name) `thenRn_`
+                 addWarnRn (importDeclWarn name) `thenRn_`
                  returnRn Nothing
        else
        getNonWiredInDecl name
@@ -460,7 +468,7 @@ importDecl name
 getNonWiredInDecl :: Name -> RnMG (Maybe (Module, RdrNameHsDecl))
 getNonWiredInDecl needed_name 
   = traceRn doc_str                            `thenRn_`
-    loadHomeInterface doc_str needed_name      `thenRn` \ (_, ifaces) ->
+    loadHomeInterface doc_str needed_name      `thenRn` \ ifaces ->
     case lookupNameEnv (iDecls ifaces) needed_name of
 
       Just (version,avail,_,decl)
@@ -530,33 +538,42 @@ getInterfaceExports mod_name from
 \begin{code}
 getImportedInstDecls :: NameSet -> RnMG [(Module,RdrNameHsDecl)]
 getImportedInstDecls gates
-  =    -- First load any orphan-instance modules that aren't aready loaded
+  =            -- First, load any orphan-instance modules that aren't aready loaded
        -- Orphan-instance modules are recorded in the module dependecnies
-    getIfacesRn                                                `thenRn` \ ifaces ->
+    getIfacesRn                                        `thenRn` \ ifaces ->
     let
        orphan_mods =
          [mod | (mod, (_, True, Nothing)) <- fmToList (iImpModInfo ifaces)]
     in
-    traceRn (text "Loading orphan modules" <+> fsep (map pprModuleName orphan_mods))
-    `thenRn_` mapRn_ load_it orphan_mods       `thenRn_`
+    loadOrphanModules orphan_mods                      `thenRn_` 
 
        -- Now we're ready to grab the instance declarations
        -- Find the un-gated ones and return them, 
        -- removing them from the bag kept in Ifaces
-    getIfacesRn                                                `thenRn` \ ifaces ->
+    getIfacesRn                                        `thenRn` \ ifaces ->
     let
        (decls, new_insts) = selectGated gates (iInsts ifaces)
     in
     setIfacesRn (ifaces { iInsts = new_insts })                `thenRn_`
 
     traceRn (sep [text "getImportedInstDecls:", 
-                 nest 4 (fsep (map ppr (nameSetToList gates))),
-                 text "Slurped" <+> int (length decls)
-                                <+> text "instance declarations"]) `thenRn_`
+                 nest 4 (fsep (map ppr gate_list)),
+                 text "Slurped" <+> int (length decls) <+> text "instance declarations",
+                 nest 4 (vcat (map ppr_brief_inst_decl decls))])       `thenRn_`
     returnRn decls
   where
-    load_it mod = loadInterface (doc_str mod) mod ImportBySystem
-    doc_str mod = sep [pprModuleName mod, ptext SLIT("is a orphan-instance module")]
+    gate_list      = nameSetToList gates
+
+    load_home gate | isLocallyDefined gate
+                  = returnRn ()
+                  | otherwise
+                  = loadHomeInterface (ppr gate <+> text "is an instance gate") gate   `thenRn_`
+                    returnRn ()
+
+ppr_brief_inst_decl (mod, InstD (InstDecl inst_ty _ _ _ _))
+  = case inst_ty of
+       HsForAllTy _ _ tau -> ppr tau
+       other              -> ppr inst_ty
 
 getImportedRules :: RnMG [(Module,RdrNameHsDecl)]
 getImportedRules
@@ -571,6 +588,7 @@ getImportedRules
     returnRn decls
 
 selectGated gates decl_bag
+       -- Select only those decls whose gates are *all* in 'gates'
 #ifdef DEBUG
   | opt_NoPruneDecls   -- Just to try the effect of not gating at all
   = (foldrBag (\ (_,d) ds -> d:ds) [] decl_bag, emptyBag)      -- Grab them all
@@ -592,7 +610,7 @@ lookupFixity name
        Nothing                  -> returnRn defaultFixity
 
   | otherwise  -- Imported
-  = loadHomeInterface doc name         `thenRn` \ (_, ifaces) ->
+  = loadHomeInterface doc name         `thenRn` \ ifaces ->
     case lookupNameEnv (iFixes ifaces) name of
        Just (FixitySig _ fix _) -> returnRn fix 
        Nothing                  -> returnRn defaultFixity
@@ -770,11 +788,25 @@ getDeclBinders new_name (SigD (IfaceSig var ty prags src_loc))
     returnRn (Just (Avail var_name))
 
 getDeclBinders new_name (FixD _)  = returnRn Nothing
-getDeclBinders new_name (ForD _)  = returnRn Nothing
+
+    -- foreign declarations
+getDeclBinders new_name (ForD (ForeignDecl nm kind _ dyn _ loc))
+  | binds_haskell_name kind dyn
+  = new_name nm loc                `thenRn` \ name ->
+    returnRn (Just (Avail name))
+
+  | otherwise -- a foreign export
+  = lookupImplicitOccRn nm `thenRn_` 
+    returnRn Nothing
+
 getDeclBinders new_name (DefD _)  = returnRn Nothing
 getDeclBinders new_name (InstD _) = returnRn Nothing
 getDeclBinders new_name (RuleD _) = returnRn Nothing
 
+binds_haskell_name (FoImport _) _   = True
+binds_haskell_name FoLabel      _   = True
+binds_haskell_name FoExport  ext_nm = isDynamic ext_nm
+
 ----------------
 getConFieldNames new_name (ConDecl con _ _ (RecCon fielddecls) src_loc : rest)
   = mapRn (\n -> new_name n src_loc) (con:fields)      `thenRn` \ cfs ->
@@ -932,14 +964,13 @@ getDeclWarn name loc
   = sep [ptext SLIT("Failed to find (optional) interface decl for") <+> quotes (ppr name),
         ptext SLIT("desired at") <+> ppr loc]
 
-importDeclWarn mod name
+importDeclWarn name
   = sep [ptext SLIT(
     "Compiler tried to import decl from interface file with same name as module."), 
         ptext SLIT(
     "(possible cause: module name clashes with interface file already in scope.)")
        ] $$
-    hsep [ptext SLIT("Interface:"), quotes (pprModuleName mod), 
-         comma, ptext SLIT("name:"), quotes (ppr name)]
+    hsep [ptext SLIT("name:"), quotes (ppr name)]
 
 warnRedundantSourceImport mod_name
   = ptext SLIT("Unnecessary {- SOURCE -} in the import of module")