Add missing special case for GHC.Prim
[ghc-hetmet.git] / compiler / main / GHC.hs
index be47c76..eb2ca8e 100644 (file)
@@ -14,7 +14,8 @@ module GHC (
        newSession,
 
        -- * Flags and settings
        newSession,
 
        -- * Flags and settings
-       DynFlags(..), DynFlag(..), Severity(..), GhcMode(..), HscTarget(..), dopt,
+       DynFlags(..), DynFlag(..), Severity(..), HscTarget(..), dopt,
+        GhcMode(..), GhcLink(..),
        parseDynamicFlags,
        getSessionDynFlags,
        setSessionDynFlags,
        parseDynamicFlags,
        getSessionDynFlags,
        setSessionDynFlags,
@@ -40,6 +41,9 @@ module GHC (
        checkModule, CheckedModule(..),
        TypecheckedSource, ParsedSource, RenamedSource,
 
        checkModule, CheckedModule(..),
        TypecheckedSource, ParsedSource, RenamedSource,
 
+       -- * Parsing Haddock comments
+       parseHaddockComment,
+
        -- * Inspecting the module structure of the program
        ModuleGraph, ModSummary(..), ms_mod_name, ModLocation(..),
        getModuleGraph,
        -- * Inspecting the module structure of the program
        ModuleGraph, ModSummary(..), ms_mod_name, ModLocation(..),
        getModuleGraph,
@@ -56,6 +60,9 @@ module GHC (
        modInfoInstances,
        modInfoIsExportedName,
        modInfoLookupName,
        modInfoInstances,
        modInfoIsExportedName,
        modInfoLookupName,
+#if defined(GHCI)
+        modInfoBkptSites,
+#endif
        lookupGlobalName,
 
        -- * Printing
        lookupGlobalName,
 
        -- * Printing
@@ -76,8 +83,12 @@ module GHC (
        RunResult(..),
        runStmt,
        showModule,
        RunResult(..),
        runStmt,
        showModule,
+        isModuleInterpreted,
        compileExpr, HValue, dynCompileExpr,
        lookupName,
        compileExpr, HValue, dynCompileExpr,
        lookupName,
+
+        getBreakpointHandler, setBreakpointHandler, 
+        obtainTerm, obtainTerm1,
 #endif
 
        -- * Abstract syntax elements
 #endif
 
        -- * Abstract syntax elements
@@ -91,7 +102,7 @@ module GHC (
 
        -- ** Names
        Name, 
 
        -- ** Names
        Name, 
-       nameModule, nameParent_maybe, pprParenSymName, nameSrcLoc,
+       nameModule, pprParenSymName, nameSrcLoc,
        NamedThing(..),
        RdrName(Qual,Unqual),
        
        NamedThing(..),
        RdrName(Qual,Unqual),
        
@@ -109,7 +120,8 @@ module GHC (
        TyCon, 
        tyConTyVars, tyConDataCons, tyConArity,
        isClassTyCon, isSynTyCon, isNewTyCon, isPrimTyCon, isFunTyCon,
        TyCon, 
        tyConTyVars, tyConDataCons, tyConArity,
        isClassTyCon, isSynTyCon, isNewTyCon, isPrimTyCon, isFunTyCon,
-       synTyConDefn, synTyConRhs,
+       isOpenTyCon,
+       synTyConDefn, synTyConType, synTyConResKind,
 
        -- ** Type variables
        TyVar,
 
        -- ** Type variables
        TyVar,
@@ -132,7 +144,8 @@ module GHC (
        instanceDFunId, pprInstance, pprInstanceHdr,
 
        -- ** Types and Kinds
        instanceDFunId, pprInstance, pprInstanceHdr,
 
        -- ** Types and Kinds
-       Type, dropForAlls, splitForAllTys, funResultTy, pprParendType,
+       Type, dropForAlls, splitForAllTys, funResultTy, 
+       pprParendType, pprTypeApp,
        Kind,
        PredType,
        ThetaType, pprThetaArrow,
        Kind,
        PredType,
        ThetaType, pprThetaArrow,
@@ -170,9 +183,7 @@ module GHC (
 #include "HsVersions.h"
 
 #ifdef GHCI
 #include "HsVersions.h"
 
 #ifdef GHCI
-import qualified Linker
-import Data.Dynamic     ( Dynamic )
-import Linker          ( HValue, extendLinkEnv )
+import RtClosureInspect ( cvObtainTerm, Term )
 import TcRnDriver      ( tcRnLookupRdrName, tcRnGetInfo,
                          tcRnLookupName, getModuleExports )
 import RdrName         ( plusGlobalRdrEnv, Provenance(..), 
 import TcRnDriver      ( tcRnLookupRdrName, tcRnGetInfo,
                          tcRnLookupName, getModuleExports )
 import RdrName         ( plusGlobalRdrEnv, Provenance(..), 
@@ -181,8 +192,26 @@ import RdrName             ( plusGlobalRdrEnv, Provenance(..),
 import HscMain         ( hscParseIdentifier, hscStmt, hscTcExpr, hscKcType )
 import Name            ( nameOccName )
 import Type            ( tidyType )
 import HscMain         ( hscParseIdentifier, hscStmt, hscTcExpr, hscKcType )
 import Name            ( nameOccName )
 import Type            ( tidyType )
+import Var             ( varName )
 import VarEnv          ( emptyTidyEnv )
 import VarEnv          ( emptyTidyEnv )
-import GHC.Exts                ( unsafeCoerce# )
+import GHC.Exts         ( unsafeCoerce# )
+
+-- For breakpoints
+import Breakpoints      ( SiteNumber, Coord, nullBkptHandler, 
+                          BkptHandler(..), BkptLocation, noDbgSites )
+import Linker           ( initDynLinker )
+import PrelNames        ( breakpointJumpName, breakpointCondJumpName, 
+                          breakpointAutoJumpName )
+
+import GHC.Exts         ( Int(..), Ptr(..), int2Addr#, indexArray# )
+import GHC.Base         ( Opaque(..) )
+import Foreign.StablePtr( deRefStablePtr, castPtrToStablePtr )
+import Foreign          ( unsafePerformIO )
+import Data.Maybe       ( fromMaybe)
+import qualified Linker
+
+import Data.Dynamic     ( Dynamic )
+import Linker          ( HValue, getHValue, extendLinkEnv )
 #endif
 
 import Packages                ( initPackages )
 #endif
 
 import Packages                ( initPackages )
@@ -190,10 +219,10 @@ import NameSet            ( NameSet, nameSetToList, elemNameSet )
 import RdrName         ( GlobalRdrEnv, GlobalRdrElt(..), RdrName(..), 
                          globalRdrEnvElts, extendGlobalRdrEnv,
                           emptyGlobalRdrEnv )
 import RdrName         ( GlobalRdrEnv, GlobalRdrElt(..), RdrName(..), 
                          globalRdrEnvElts, extendGlobalRdrEnv,
                           emptyGlobalRdrEnv )
-import HsSyn
+import HsSyn 
 import Type            ( Kind, Type, dropForAlls, PredType, ThetaType,
                          pprThetaArrow, pprParendType, splitForAllTys,
 import Type            ( Kind, Type, dropForAlls, PredType, ThetaType,
                          pprThetaArrow, pprParendType, splitForAllTys,
-                         funResultTy )
+                         pprTypeApp, funResultTy )
 import Id              ( Id, idType, isImplicitId, isDeadBinder,
                           isExportedId, isLocalId, isGlobalId,
                           isRecordSelector, recordSelectorFieldLabel,
 import Id              ( Id, idType, isImplicitId, isDeadBinder,
                           isExportedId, isLocalId, isGlobalId,
                           isRecordSelector, recordSelectorFieldLabel,
@@ -203,15 +232,15 @@ import Id         ( Id, idType, isImplicitId, isDeadBinder,
 import Var             ( TyVar )
 import TysPrim         ( alphaTyVars )
 import TyCon           ( TyCon, isClassTyCon, isSynTyCon, isNewTyCon,
 import Var             ( TyVar )
 import TysPrim         ( alphaTyVars )
 import TyCon           ( TyCon, isClassTyCon, isSynTyCon, isNewTyCon,
-                         isPrimTyCon, isFunTyCon, tyConArity,
-                         tyConTyVars, tyConDataCons, synTyConDefn, synTyConRhs )
+                         isPrimTyCon, isFunTyCon, isOpenTyCon, tyConArity,
+                         tyConTyVars, tyConDataCons, synTyConDefn,
+                         synTyConType, synTyConResKind )
 import Class           ( Class, classSCTheta, classTvsFds, classMethods )
 import FunDeps         ( pprFundeps )
 import DataCon         ( DataCon, dataConWrapId, dataConSig, dataConTyCon,
                          dataConFieldLabels, dataConStrictMarks, 
                          dataConIsInfix, isVanillaDataCon )
 import Class           ( Class, classSCTheta, classTvsFds, classMethods )
 import FunDeps         ( pprFundeps )
 import DataCon         ( DataCon, dataConWrapId, dataConSig, dataConTyCon,
                          dataConFieldLabels, dataConStrictMarks, 
                          dataConIsInfix, isVanillaDataCon )
-import Name            ( Name, nameModule, NamedThing(..), nameParent_maybe,
-                         nameSrcLoc )
+import Name            ( Name, nameModule, NamedThing(..), nameSrcLoc )
 import OccName         ( parenSymOcc )
 import NameEnv         ( nameEnvElts )
 import InstEnv         ( Instance, instanceDFunId, pprInstance, pprInstanceHdr )
 import OccName         ( parenSymOcc )
 import NameEnv         ( nameEnvElts )
 import InstEnv         ( Instance, instanceDFunId, pprInstance, pprInstanceHdr )
@@ -227,13 +256,14 @@ import SysTools     ( initSysTools, cleanTempFiles, cleanTempFilesExcept,
                       cleanTempDirs )
 import Module
 import UniqFM
                       cleanTempDirs )
 import Module
 import UniqFM
-import PackageConfig    ( PackageId, stringToPackageId )
+import PackageConfig    ( PackageId, stringToPackageId, mainPackageId )
 import FiniteMap
 import Panic
 import Digraph
 import FiniteMap
 import Panic
 import Digraph
-import Bag             ( unitBag )
+import Bag             ( unitBag, listToBag )
 import ErrUtils                ( Severity(..), showPass, fatalErrorMsg, debugTraceMsg,
 import ErrUtils                ( Severity(..), showPass, fatalErrorMsg, debugTraceMsg,
-                         mkPlainErrMsg, printBagOfErrors )
+                         mkPlainErrMsg, printBagOfErrors, printBagOfWarnings,
+                         WarnMsg )
 import qualified ErrUtils
 import Util
 import StringBuffer    ( StringBuffer, hGetStringBuffer )
 import qualified ErrUtils
 import Util
 import StringBuffer    ( StringBuffer, hGetStringBuffer )
@@ -241,6 +271,8 @@ import Outputable
 import BasicTypes
 import TcType           ( tcSplitSigmaTy, isDictTy )
 import Maybes          ( expectJust, mapCatMaybes )
 import BasicTypes
 import TcType           ( tcSplitSigmaTy, isDictTy )
 import Maybes          ( expectJust, mapCatMaybes )
+import HaddockParse     ( parseHaddockParagraphs, parseHaddockString )
+import HaddockLex       ( tokenise )
 
 import Control.Concurrent
 import System.Directory ( getModificationTime, doesFileExist )
 
 import Control.Concurrent
 import System.Directory ( getModificationTime, doesFileExist )
@@ -308,9 +340,8 @@ defaultErrorHandler dflags inner =
 defaultCleanupHandler :: DynFlags -> IO a -> IO a
 defaultCleanupHandler dflags inner = 
     -- make sure we clean up after ourselves
 defaultCleanupHandler :: DynFlags -> IO a -> IO a
 defaultCleanupHandler dflags inner = 
     -- make sure we clean up after ourselves
-    later (unless (dopt Opt_KeepTmpFiles dflags) $
-               do cleanTempFiles dflags
-                  cleanTempDirs dflags
+    later (do cleanTempFiles dflags
+              cleanTempDirs dflags
           )
           -- exceptions will be blocked while we clean the temporary files,
           -- so there shouldn't be any difficulty if we receive further
           )
           -- exceptions will be blocked while we clean the temporary files,
           -- so there shouldn't be any difficulty if we receive further
@@ -318,20 +349,24 @@ defaultCleanupHandler dflags inner =
     inner
 
 
     inner
 
 
+#if defined(GHCI) 
+GLOBAL_VAR(v_bkptLinkEnv, [], [(Name, HValue)])
+        -- stores the current breakpoint handler to help setContext to
+        -- restore it after a context change
+#endif
+
 -- | Starts a new session.  A session consists of a set of loaded
 -- modules, a set of options (DynFlags), and an interactive context.
 -- | Starts a new session.  A session consists of a set of loaded
 -- modules, a set of options (DynFlags), and an interactive context.
--- ToDo: GhcMode should say "keep typechecked code" and\/or "keep renamed
--- code".
-newSession :: GhcMode -> Maybe FilePath -> IO Session
-newSession mode mb_top_dir = do
+newSession :: Maybe FilePath -> IO Session
+newSession mb_top_dir = do
   -- catch ^C
   main_thread <- myThreadId
   -- catch ^C
   main_thread <- myThreadId
-  putMVar interruptTargetThread [main_thread]
+  modifyMVar_ interruptTargetThread (return . (main_thread :))
   installSignalHandlers
 
   dflags0 <- initSysTools mb_top_dir defaultDynFlags
   dflags  <- initDynFlags dflags0
   installSignalHandlers
 
   dflags0 <- initSysTools mb_top_dir defaultDynFlags
   dflags  <- initDynFlags dflags0
-  env <- newHscEnv dflags{ ghcMode=mode }
+  env <- newHscEnv dflags
   ref <- newIORef env
   return (Session ref)
 
   ref <- newIORef env
   return (Session ref)
 
@@ -472,6 +507,12 @@ setGlobalTypeScope session ids
       hscEnv{ hsc_global_type_env = extendTypeEnvWithIds emptyTypeEnv ids }
 
 -- -----------------------------------------------------------------------------
       hscEnv{ hsc_global_type_env = extendTypeEnvWithIds emptyTypeEnv ids }
 
 -- -----------------------------------------------------------------------------
+-- Parsing Haddock comments
+
+parseHaddockComment :: String -> Either String (HsDoc RdrName)
+parseHaddockComment string = parseHaddockParagraphs (tokenise string)
+
+-- -----------------------------------------------------------------------------
 -- Loading the program
 
 -- Perform a dependency analysis starting from the current targets
 -- Loading the program
 
 -- Perform a dependency analysis starting from the current targets
@@ -486,10 +527,9 @@ depanal (Session ref) excluded_mods allow_dup_roots = do
         old_graph = hsc_mod_graph hsc_env
        
   showPass dflags "Chasing dependencies"
         old_graph = hsc_mod_graph hsc_env
        
   showPass dflags "Chasing dependencies"
-  when (gmode == BatchCompile) $
-       debugTraceMsg dflags 2 (hcat [
-                    text "Chasing modules from: ",
-                       hcat (punctuate comma (map pprTarget targets))])
+  debugTraceMsg dflags 2 (hcat [
+            text "Chasing modules from: ",
+            hcat (punctuate comma (map pprTarget targets))])
 
   r <- downsweep hsc_env old_graph excluded_mods allow_dup_roots
   case r of
 
   r <- downsweep hsc_env old_graph excluded_mods allow_dup_roots
   case r of
@@ -561,10 +601,14 @@ load2 s@(Session ref) how_much mod_graph = do
         let mg2_with_srcimps :: [SCC ModSummary]
            mg2_with_srcimps = topSortModuleGraph True mod_graph Nothing
 
         let mg2_with_srcimps :: [SCC ModSummary]
            mg2_with_srcimps = topSortModuleGraph True mod_graph Nothing
 
+       -- If we can determine that any of the {-# SOURCE #-} imports
+       -- are definitely unnecessary, then emit a warning.
+       warnUnnecessarySourceImports dflags mg2_with_srcimps
+
+       let
            -- check the stability property for each module.
            stable_mods@(stable_obj,stable_bco)
            -- check the stability property for each module.
            stable_mods@(stable_obj,stable_bco)
-               | BatchCompile <- ghci_mode = ([],[])
-               | otherwise = checkStability hpt1 mg2_with_srcimps all_home_mods
+               = checkStability hpt1 mg2_with_srcimps all_home_mods
 
            -- prune bits of the HPT which are definitely redundant now,
            -- to save space.
 
            -- prune bits of the HPT which are definitely redundant now,
            -- to save space.
@@ -635,6 +679,8 @@ load2 s@(Session ref) how_much mod_graph = do
        let cleanup = cleanTempFilesExcept dflags
                          (ppFilesFromSummaries (flattenSCCs mg2_with_srcimps))
 
        let cleanup = cleanTempFilesExcept dflags
                          (ppFilesFromSummaries (flattenSCCs mg2_with_srcimps))
 
+       debugTraceMsg dflags 2 (hang (text "Ready for upsweep") 
+                                  2 (ppr mg))
         (upsweep_ok, hsc_env1, modsUpswept)
            <- upsweep (hsc_env { hsc_HPT = emptyHomePackageTable })
                           pruned_hpt stable_mods cleanup mg
         (upsweep_ok, hsc_env1, modsUpswept)
            <- upsweep (hsc_env { hsc_HPT = emptyHomePackageTable })
                           pruned_hpt stable_mods cleanup mg
@@ -670,13 +716,16 @@ load2 s@(Session ref) how_much mod_graph = do
                a_root_is_Main = any ((==main_mod).ms_mod) mod_graph
                do_linking = a_root_is_Main || no_hs_main
 
                a_root_is_Main = any ((==main_mod).ms_mod) mod_graph
                do_linking = a_root_is_Main || no_hs_main
 
-             when (ghci_mode == BatchCompile && isJust ofile && not do_linking) $
-               debugTraceMsg dflags 1 (text ("Warning: output was redirected with -o, " ++
-                                             "but no output will be generated\n" ++
-                                             "because there is no " ++ moduleNameString (moduleName main_mod) ++ " module."))
+             when (ghcLink dflags == LinkBinary 
+                    && isJust ofile && not do_linking) $
+               debugTraceMsg dflags 1 $
+                    text ("Warning: output was redirected with -o, " ++
+                          "but no output will be generated\n" ++
+                         "because there is no " ++ 
+                          moduleNameString (moduleName main_mod) ++ " module.")
 
              -- link everything together
 
              -- link everything together
-              linkresult <- link ghci_mode dflags do_linking (hsc_HPT hsc_env1)
+              linkresult <- link (ghcLink dflags) dflags do_linking (hsc_HPT hsc_env1)
 
              loadFinish Succeeded linkresult ref hsc_env1
 
 
              loadFinish Succeeded linkresult ref hsc_env1
 
@@ -706,7 +755,7 @@ load2 s@(Session ref) how_much mod_graph = do
                        (eltsUFM (hsc_HPT hsc_env))) do
        
              -- Link everything together
                        (eltsUFM (hsc_HPT hsc_env))) do
        
              -- Link everything together
-              linkresult <- link ghci_mode dflags False hpt4
+              linkresult <- link (ghcLink dflags) dflags False hpt4
 
              let hsc_env4 = hsc_env1{ hsc_HPT = hpt4 }
              loadFinish Failed linkresult ref hsc_env4
 
              let hsc_env4 = hsc_env1{ hsc_HPT = hpt4 }
              loadFinish Failed linkresult ref hsc_env4
@@ -754,7 +803,8 @@ data CheckedModule =
        --  fields within CheckedModule.
 
 type ParsedSource      = Located (HsModule RdrName)
        --  fields within CheckedModule.
 
 type ParsedSource      = Located (HsModule RdrName)
-type RenamedSource     = (HsGroup Name, [LImportDecl Name], Maybe [LIE Name])
+type RenamedSource     = (HsGroup Name, [LImportDecl Name], Maybe [LIE Name],
+                          Maybe (HsDoc Name), HaddockModInfo Name)
 type TypecheckedSource = LHsBinds Id
 
 -- NOTE:
 type TypecheckedSource = LHsBinds Id
 
 -- NOTE:
@@ -799,9 +849,13 @@ checkModule session@(Session ref) mod = do
                           (Just (tc_binds, rdr_env, details))) -> do
                   let minf = ModuleInfo {
                                minf_type_env  = md_types details,
                           (Just (tc_binds, rdr_env, details))) -> do
                   let minf = ModuleInfo {
                                minf_type_env  = md_types details,
-                               minf_exports   = md_exports details,
+                               minf_exports   = availsToNameSet $
+                                                     md_exports details,
                                minf_rdr_env   = Just rdr_env,
                                minf_instances = md_insts details
                                minf_rdr_env   = Just rdr_env,
                                minf_instances = md_insts details
+#ifdef GHCI
+                               ,minf_dbg_sites = noDbgSites
+#endif
                              }
                   return (Just (CheckedModule {
                                        parsedSource = parsed,
                              }
                   return (Just (CheckedModule {
                                        parsedSource = parsed,
@@ -814,15 +868,13 @@ checkModule session@(Session ref) mod = do
 
 unload :: HscEnv -> [Linkable] -> IO ()
 unload hsc_env stable_linkables        -- Unload everthing *except* 'stable_linkables'
 
 unload :: HscEnv -> [Linkable] -> IO ()
 unload hsc_env stable_linkables        -- Unload everthing *except* 'stable_linkables'
-  = case ghcMode (hsc_dflags hsc_env) of
-       BatchCompile  -> return ()
-       JustTypecheck -> return ()
+  = case ghcLink (hsc_dflags hsc_env) of
 #ifdef GHCI
 #ifdef GHCI
-       Interactive -> Linker.unload (hsc_dflags hsc_env) stable_linkables
+       LinkInMemory -> Linker.unload (hsc_dflags hsc_env) stable_linkables
 #else
 #else
-       Interactive -> panic "unload: no interpreter"
+       LinkInMemory -> panic "unload: no interpreter"
 #endif
 #endif
-       other -> panic "unload: strange mode"
+       other -> return ()
 
 -- -----------------------------------------------------------------------------
 -- checkStability
 
 -- -----------------------------------------------------------------------------
 -- checkStability
@@ -839,9 +891,6 @@ unload hsc_env stable_linkables     -- Unload everthing *except* 'stable_linkables'
      module.  So we need to know that we will definitely not be recompiling
      any of these modules, and we can use the object code.
 
      module.  So we need to know that we will definitely not be recompiling
      any of these modules, and we can use the object code.
 
-  NB. stability is of no importance to BatchCompile at all, only Interactive.
-  (ToDo: what about JustTypecheck?)
-
   The stability check is as follows.  Both stableObject and
   stableBCO are used during the upsweep phase later.
 
   The stability check is as follows.  Both stableObject and
   stableBCO are used during the upsweep phase later.
 
@@ -860,7 +909,7 @@ unload hsc_env stable_linkables     -- Unload everthing *except* 'stable_linkables'
 
   These properties embody the following ideas:
 
 
   These properties embody the following ideas:
 
-    - if a module is stable:
+    - if a module is stable, then:
        - if it has been compiled in a previous pass (present in HPT)
          then it does not need to be compiled or re-linked.
         - if it has not been compiled in a previous pass,
        - if it has been compiled in a previous pass (present in HPT)
          then it does not need to be compiled or re-linked.
         - if it has not been compiled in a previous pass,
@@ -1071,95 +1120,133 @@ upsweep_mod :: HscEnv
             -> IO (Maybe HomeModInfo)  -- Nothing => Failed
 
 upsweep_mod hsc_env old_hpt (stable_obj, stable_bco) summary mod_index nmods
             -> IO (Maybe HomeModInfo)  -- Nothing => Failed
 
 upsweep_mod hsc_env old_hpt (stable_obj, stable_bco) summary mod_index nmods
-   = do 
-        let 
-           this_mod_name = ms_mod_name summary
+   =    let 
+                   this_mod_name = ms_mod_name summary
            this_mod    = ms_mod summary
            mb_obj_date = ms_obj_date summary
            obj_fn      = ml_obj_file (ms_location summary)
            hs_date     = ms_hs_date summary
 
            this_mod    = ms_mod summary
            mb_obj_date = ms_obj_date summary
            obj_fn      = ml_obj_file (ms_location summary)
            hs_date     = ms_hs_date summary
 
+           is_stable_obj = this_mod_name `elem` stable_obj
+           is_stable_bco = this_mod_name `elem` stable_bco
+
+           old_hmi = lookupUFM old_hpt this_mod_name
+
+            -- We're using the dflags for this module now, obtained by
+            -- applying any options in its LANGUAGE & OPTIONS_GHC pragmas.
+            dflags = ms_hspp_opts summary
+            prevailing_target = hscTarget (hsc_dflags hsc_env)
+            local_target      = hscTarget dflags
+
+            -- If OPTIONS_GHC contains -fasm or -fvia-C, be careful that
+            -- we don't do anything dodgy: these should only work to change
+            -- from -fvia-C to -fasm and vice-versa, otherwise we could 
+            -- end up trying to link object code to byte code.
+            target = if prevailing_target /= local_target
+                        && (not (isObjectTarget prevailing_target)
+                            || not (isObjectTarget local_target))
+                        then prevailing_target
+                        else local_target 
+
+            -- store the corrected hscTarget into the summary
+            summary' = summary{ ms_hspp_opts = dflags { hscTarget = target } }
+
+           -- The old interface is ok if
+           --  a) we're compiling a source file, and the old HPT
+           --     entry is for a source file
+           --  b) we're compiling a hs-boot file
+           -- Case (b) allows an hs-boot file to get the interface of its
+           -- real source file on the second iteration of the compilation
+           -- manager, but that does no harm.  Otherwise the hs-boot file
+           -- will always be recompiled
+            
+            mb_old_iface 
+               = case old_hmi of
+                    Nothing                              -> Nothing
+                    Just hm_info | isBootSummary summary -> Just iface
+                                 | not (mi_boot iface)   -> Just iface
+                                 | otherwise             -> Nothing
+                                  where 
+                                    iface = hm_iface hm_info
+
            compile_it :: Maybe Linkable -> IO (Maybe HomeModInfo)
            compile_it  = upsweep_compile hsc_env old_hpt this_mod_name 
            compile_it :: Maybe Linkable -> IO (Maybe HomeModInfo)
            compile_it  = upsweep_compile hsc_env old_hpt this_mod_name 
-                               summary mod_index nmods
-
-       case ghcMode (hsc_dflags hsc_env) of
-           BatchCompile ->
-               case () of
-                  -- Batch-compilating is easy: just check whether we have
-                  -- an up-to-date object file.  If we do, then the compiler
-                  -- needs to do a recompilation check.
-                  _ | Just obj_date <- mb_obj_date, obj_date >= hs_date -> do
-                          linkable <- 
-                               findObjectLinkable this_mod obj_fn obj_date
-                          compile_it (Just linkable)
-
-                    | otherwise ->
-                          compile_it Nothing
-
-           interactive ->
-               case () of
-                   _ | is_stable_obj, isJust old_hmi ->
-                          return old_hmi
+                               summary' mod_index nmods mb_old_iface
+
+            compile_it_discard_iface 
+                        = upsweep_compile hsc_env old_hpt this_mod_name 
+                               summary' mod_index nmods Nothing
+
+        in
+       case target of
+
+            _any
+                -- Regardless of whether we're generating object code or
+                -- byte code, we can always use an existing object file
+                -- if it is *stable* (see checkStability).
+               | is_stable_obj, isJust old_hmi ->
+                       return old_hmi
                        -- object is stable, and we have an entry in the
                        -- old HPT: nothing to do
 
                        -- object is stable, and we have an entry in the
                        -- old HPT: nothing to do
 
-                     | is_stable_obj, isNothing old_hmi -> do
-                          linkable <-
-                               findObjectLinkable this_mod obj_fn 
+               | is_stable_obj, isNothing old_hmi -> do
+                       linkable <- findObjectLinkable this_mod obj_fn 
                                        (expectJust "upseep1" mb_obj_date)
                                        (expectJust "upseep1" mb_obj_date)
-                          compile_it (Just linkable)
+                       compile_it (Just linkable)
                        -- object is stable, but we need to load the interface
                        -- off disk to make a HMI.
 
                        -- object is stable, but we need to load the interface
                        -- off disk to make a HMI.
 
-                     | is_stable_bco -> 
-                          ASSERT(isJust old_hmi) -- must be in the old_hpt
-                          return old_hmi
+            HscInterpreted
+               | is_stable_bco -> 
+                       ASSERT(isJust old_hmi) -- must be in the old_hpt
+                       return old_hmi
                        -- BCO is stable: nothing to do
 
                        -- BCO is stable: nothing to do
 
-                     | Just hmi <- old_hmi,
-                       Just l <- hm_linkable hmi, not (isObjectLinkable l),
-                       linkableTime l >= ms_hs_date summary ->
-                          compile_it (Just l)
+               | Just hmi <- old_hmi,
+                 Just l <- hm_linkable hmi, not (isObjectLinkable l),
+                 linkableTime l >= ms_hs_date summary ->
+                       compile_it (Just l)
                        -- we have an old BCO that is up to date with respect
                        -- to the source: do a recompilation check as normal.
 
                        -- we have an old BCO that is up to date with respect
                        -- to the source: do a recompilation check as normal.
 
-                     | otherwise ->
-                         compile_it Nothing
+               | otherwise -> 
+                        compile_it Nothing
                        -- no existing code at all: we must recompile.
                        -- no existing code at all: we must recompile.
-                  where
-                   is_stable_obj = this_mod_name `elem` stable_obj
-                   is_stable_bco = this_mod_name `elem` stable_bco
 
 
-                   old_hmi = lookupUFM old_hpt this_mod_name
+              -- When generating object code, if there's an up-to-date
+              -- object file on the disk, then we can use it.
+              -- However, if the object file is new (compared to any
+              -- linkable we had from a previous compilation), then we
+              -- must discard any in-memory interface, because this
+              -- means the user has compiled the source file
+              -- separately and generated a new interface, that we must
+              -- read from the disk.
+              --
+            obj | isObjectTarget obj,
+                 Just obj_date <- mb_obj_date, obj_date >= hs_date -> do
+                     case old_hmi of
+                        Just hmi 
+                          | Just l <- hm_linkable hmi,
+                            isObjectLinkable l && linkableTime l == obj_date
+                            -> compile_it (Just l)
+                        _otherwise -> do
+                         linkable <- findObjectLinkable this_mod obj_fn obj_date
+                          compile_it_discard_iface (Just linkable)
+
+           _otherwise ->
+                 compile_it Nothing
+
 
 -- Run hsc to compile a module
 upsweep_compile hsc_env old_hpt this_mod summary
                 mod_index nmods
 
 -- Run hsc to compile a module
 upsweep_compile hsc_env old_hpt this_mod summary
                 mod_index nmods
-                mb_old_linkable = do
-  let
-       -- The old interface is ok if it's in the old HPT 
-       --      a) we're compiling a source file, and the old HPT
-       --         entry is for a source file
-       --      b) we're compiling a hs-boot file
-       -- Case (b) allows an hs-boot file to get the interface of its
-       -- real source file on the second iteration of the compilation
-       -- manager, but that does no harm.  Otherwise the hs-boot file
-       -- will always be recompiled
-
-        mb_old_iface 
-               = case lookupUFM old_hpt this_mod of
-                    Nothing                              -> Nothing
-                    Just hm_info | isBootSummary summary -> Just iface
-                                 | not (mi_boot iface)   -> Just iface
-                                 | otherwise             -> Nothing
-                                  where 
-                                    iface = hm_iface hm_info
-
-  compresult <- compile hsc_env summary mb_old_linkable mb_old_iface
+                mb_old_iface
+                mb_old_linkable
+ = do
+   compresult <- compile hsc_env summary mb_old_linkable mb_old_iface
                         mod_index nmods
 
                         mod_index nmods
 
-  case compresult of
+   case compresult of
         -- Compilation failed.  Compile may still have updated the PCS, tho.
         CompErrs -> return Nothing
 
         -- Compilation failed.  Compile may still have updated the PCS, tho.
         CompErrs -> return Nothing
 
@@ -1229,13 +1316,29 @@ moduleGraphNodes drop_hs_boot_nodes summaries = (nodes, lookup_key)
 
        -- We use integers as the keys for the SCC algorithm
        nodes :: [(ModSummary, Int, [Int])]     
 
        -- We use integers as the keys for the SCC algorithm
        nodes :: [(ModSummary, Int, [Int])]     
-       nodes = [(s, expectJust "topSort" (lookup_key (ms_hsc_src s) (ms_mod_name s)), 
+       nodes = [(s, expectJust "topSort" $ 
+                       lookup_key (ms_hsc_src s) (ms_mod_name s),
                     out_edge_keys hs_boot_key (map unLoc (ms_srcimps s)) ++
                     out_edge_keys hs_boot_key (map unLoc (ms_srcimps s)) ++
-                    out_edge_keys HsSrcFile   (map unLoc (ms_imps s))    )
+                    out_edge_keys HsSrcFile   (map unLoc (ms_imps s)) ++
+                    (-- see [boot-edges] below
+                     if drop_hs_boot_nodes || ms_hsc_src s == HsBootFile 
+                       then [] 
+                       else case lookup_key HsBootFile (ms_mod_name s) of
+                               Nothing -> []
+                               Just k  -> [k])
+                )
                | s <- summaries
                , not (isBootSummary s && drop_hs_boot_nodes) ]
                -- Drop the hi-boot ones if told to do so
 
                | s <- summaries
                , not (isBootSummary s && drop_hs_boot_nodes) ]
                -- Drop the hi-boot ones if told to do so
 
+       -- [boot-edges] if this is a .hs and there is an equivalent
+       -- .hs-boot, add a link from the former to the latter.  This
+       -- has the effect of detecting bogus cases where the .hs-boot
+       -- depends on the .hs, by introducing a cycle.  Additionally,
+       -- it ensures that we will always process the .hs-boot before
+       -- the .hs, and so the HomePackageTable will always have the
+       -- most up to date information.
+
        key_map :: NodeMap Int
        key_map = listToFM ([(moduleName (ms_mod s), ms_hsc_src s)
                            | s <- summaries]
        key_map :: NodeMap Int
        key_map = listToFM ([(moduleName (ms_mod s), ms_hsc_src s)
                            | s <- summaries]
@@ -1265,6 +1368,24 @@ nodeMapElts = eltsFM
 ms_mod_name :: ModSummary -> ModuleName
 ms_mod_name = moduleName . ms_mod
 
 ms_mod_name :: ModSummary -> ModuleName
 ms_mod_name = moduleName . ms_mod
 
+-- If there are {-# SOURCE #-} imports between strongly connected
+-- components in the topological sort, then those imports can
+-- definitely be replaced by ordinary non-SOURCE imports: if SOURCE
+-- were necessary, then the edge would be part of a cycle.
+warnUnnecessarySourceImports :: DynFlags -> [SCC ModSummary] -> IO ()
+warnUnnecessarySourceImports dflags sccs = 
+  printBagOfWarnings dflags (listToBag (concat (map (check.flattenSCC) sccs)))
+  where check ms =
+          let mods_in_this_cycle = map ms_mod_name ms in
+          [ warn m i | m <- ms, i <- ms_srcimps m,
+                       unLoc i `notElem`  mods_in_this_cycle ]
+
+       warn :: ModSummary -> Located ModuleName -> WarnMsg
+       warn ms (L loc mod) = 
+          mkPlainErrMsg loc
+               (ptext SLIT("Warning: {-# SOURCE #-} unnecessary in import of ")
+                <+> quotes (ppr mod))
+
 -----------------------------------------------------------------------------
 -- Downsweep (dependency analysis)
 
 -----------------------------------------------------------------------------
 -- Downsweep (dependency analysis)
 
@@ -1674,9 +1795,12 @@ getPrintUnqual s = withSession s (return . icPrintUnqual . hsc_IC)
 -- | Container for information about a 'Module'.
 data ModuleInfo = ModuleInfo {
        minf_type_env  :: TypeEnv,
 -- | Container for information about a 'Module'.
 data ModuleInfo = ModuleInfo {
        minf_type_env  :: TypeEnv,
-       minf_exports   :: NameSet,
+       minf_exports   :: NameSet, -- ToDo, [AvailInfo] like ModDetails?
        minf_rdr_env   :: Maybe GlobalRdrEnv,   -- Nothing for a compiled/package mod
        minf_instances :: [Instance]
        minf_rdr_env   :: Maybe GlobalRdrEnv,   -- Nothing for a compiled/package mod
        minf_instances :: [Instance]
+#ifdef GHCI
+        ,minf_dbg_sites :: [(SiteNumber,Coord)] 
+#endif
        -- ToDo: this should really contain the ModIface too
   }
        -- We don't want HomeModInfo here, because a ModuleInfo applies
        -- ToDo: this should really contain the ModIface too
   }
        -- We don't want HomeModInfo here, because a ModuleInfo applies
@@ -1700,22 +1824,23 @@ getModuleInfo s mdl = withSession s $ \hsc_env -> do
 getPackageModuleInfo :: HscEnv -> Module -> IO (Maybe ModuleInfo)
 getPackageModuleInfo hsc_env mdl = do
 #ifdef GHCI
 getPackageModuleInfo :: HscEnv -> Module -> IO (Maybe ModuleInfo)
 getPackageModuleInfo hsc_env mdl = do
 #ifdef GHCI
-  (_msgs, mb_names) <- getModuleExports hsc_env mdl
-  case mb_names of
+  (_msgs, mb_avails) <- getModuleExports hsc_env mdl
+  case mb_avails of
     Nothing -> return Nothing
     Nothing -> return Nothing
-    Just names -> do
+    Just avails -> do
        eps <- readIORef (hsc_EPS hsc_env)
        let 
        eps <- readIORef (hsc_EPS hsc_env)
        let 
+            names  = availsToNameSet avails
            pte    = eps_PTE eps
            pte    = eps_PTE eps
-           n_list = nameSetToList names
-           tys    = [ ty | name <- n_list,
+           tys    = [ ty | name <- concatMap availNames avails,
                            Just ty <- [lookupTypeEnv pte name] ]
        --
        return (Just (ModuleInfo {
                        minf_type_env  = mkTypeEnv tys,
                        minf_exports   = names,
                        minf_rdr_env   = Just $! nameSetToGlobalRdrEnv names (moduleName mdl),
                            Just ty <- [lookupTypeEnv pte name] ]
        --
        return (Just (ModuleInfo {
                        minf_type_env  = mkTypeEnv tys,
                        minf_exports   = names,
                        minf_rdr_env   = Just $! nameSetToGlobalRdrEnv names (moduleName mdl),
-                       minf_instances = error "getModuleInfo: instances for package module unimplemented"
+                       minf_instances = error "getModuleInfo: instances for package module unimplemented",
+                        minf_dbg_sites = noDbgSites
                }))
 #else
   -- bogusly different for non-GHCI (ToDo)
                }))
 #else
   -- bogusly different for non-GHCI (ToDo)
@@ -1729,9 +1854,12 @@ getHomeModuleInfo hsc_env mdl =
       let details = hm_details hmi
       return (Just (ModuleInfo {
                        minf_type_env  = md_types details,
       let details = hm_details hmi
       return (Just (ModuleInfo {
                        minf_type_env  = md_types details,
-                       minf_exports   = md_exports details,
+                       minf_exports   = availsToNameSet (md_exports details),
                        minf_rdr_env   = mi_globals $! hm_iface hmi,
                        minf_instances = md_insts details
                        minf_rdr_env   = mi_globals $! hm_iface hmi,
                        minf_instances = md_insts details
+#ifdef GHCI
+                       ,minf_dbg_sites = md_dbg_sites details
+#endif
                        }))
 
 -- | The list of top-level entities defined in a module
                        }))
 
 -- | The list of top-level entities defined in a module
@@ -1765,6 +1893,10 @@ modInfoLookupName s minf name = withSession s $ \hsc_env -> do
        return $! lookupType (hsc_dflags hsc_env) 
                            (hsc_HPT hsc_env) (eps_PTE eps) name
 
        return $! lookupType (hsc_dflags hsc_env) 
                            (hsc_HPT hsc_env) (eps_PTE eps) name
 
+#ifdef GHCI
+modInfoBkptSites = minf_dbg_sites
+#endif
+
 isDictonaryId :: Id -> Bool
 isDictonaryId id
   = case tcSplitSigmaTy (idType id) of { (tvs, theta, tau) -> isDictTy tau }
 isDictonaryId :: Id -> Bool
 isDictonaryId id
   = case tcSplitSigmaTy (idType id) of { (tvs, theta, tau) -> isDictTy tau }
@@ -1830,7 +1962,7 @@ findModule' hsc_env mod_name maybe_pkg =
   case lookupUFM hpt mod_name of
     Just mod_info -> return (mi_module (hm_iface mod_info))
     _not_a_home_module -> do
   case lookupUFM hpt mod_name of
     Just mod_info -> return (mi_module (hm_iface mod_info))
     _not_a_home_module -> do
-         res <- findImportedModule hsc_env mod_name Nothing
+         res <- findImportedModule hsc_env mod_name maybe_pkg
          case res of
            Found _ m | modulePackageId m /= this_pkg -> return m
                      | otherwise -> throwDyn (CmdLineError (showSDoc $
          case res of
            Found _ m | modulePackageId m /= this_pkg -> return m
                      | otherwise -> throwDyn (CmdLineError (showSDoc $
@@ -1850,7 +1982,7 @@ setContext :: Session
           -> [Module]  -- entire top level scope of these modules
           -> [Module]  -- exports only of these modules
           -> IO ()
           -> [Module]  -- entire top level scope of these modules
           -> [Module]  -- exports only of these modules
           -> IO ()
-setContext (Session ref) toplev_mods export_mods = do 
+setContext sess@(Session ref) toplev_mods export_mods = do 
   hsc_env <- readIORef ref
   let old_ic  = hsc_IC     hsc_env
       hpt     = hsc_HPT    hsc_env
   hsc_env <- readIORef ref
   let old_ic  = hsc_IC     hsc_env
       hpt     = hsc_HPT    hsc_env
@@ -1861,7 +1993,7 @@ setContext (Session ref) toplev_mods export_mods = do
   writeIORef ref hsc_env{ hsc_IC = old_ic { ic_toplev_scope = toplev_mods,
                                            ic_exports      = export_mods,
                                            ic_rn_gbl_env   = all_env }}
   writeIORef ref hsc_env{ hsc_IC = old_ic { ic_toplev_scope = toplev_mods,
                                            ic_exports      = export_mods,
                                            ic_rn_gbl_env   = all_env }}
-
+  reinstallBreakpointHandlers sess
 
 -- Make a GlobalRdrEnv based on the exports of the modules only.
 mkExportEnv :: HscEnv -> [Module] -> IO GlobalRdrEnv
 
 -- Make a GlobalRdrEnv based on the exports of the modules only.
 mkExportEnv :: HscEnv -> [Module] -> IO GlobalRdrEnv
@@ -1869,8 +2001,8 @@ mkExportEnv hsc_env mods = do
   stuff <- mapM (getModuleExports hsc_env) mods
   let 
        (_msgs, mb_name_sets) = unzip stuff
   stuff <- mapM (getModuleExports hsc_env) mods
   let 
        (_msgs, mb_name_sets) = unzip stuff
-       gres = [ nameSetToGlobalRdrEnv name_set (moduleName mod)
-              | (Just name_set, mod) <- zip mb_name_sets mods ]
+       gres = [ nameSetToGlobalRdrEnv (availsToNameSet avails) (moduleName mod)
+              | (Just avails, mod) <- zip mb_name_sets mods ]
   --
   return $! foldr plusGlobalRdrEnv emptyGlobalRdrEnv gres
 
   --
   return $! foldr plusGlobalRdrEnv emptyGlobalRdrEnv gres
 
@@ -2107,17 +2239,105 @@ sandboxIO thing = do
 foreign import "rts_evalStableIO"  {- safe -}
   rts_evalStableIO :: StablePtr (IO a) -> Ptr (StablePtr a) -> IO CInt
   -- more informative than the C type!
 foreign import "rts_evalStableIO"  {- safe -}
   rts_evalStableIO :: StablePtr (IO a) -> Ptr (StablePtr a) -> IO CInt
   -- more informative than the C type!
+
+XXX the type of rts_evalStableIO no longer matches the above
+
 -}
 
 -}
 
+
 -----------------------------------------------------------------------------
 -- show a module and it's source/object filenames
 
 showModule :: Session -> ModSummary -> IO String
 -----------------------------------------------------------------------------
 -- show a module and it's source/object filenames
 
 showModule :: Session -> ModSummary -> IO String
-showModule s mod_summary = withSession s $ \hsc_env -> do
+showModule s mod_summary = withSession s $                        \hsc_env -> 
+                           isModuleInterpreted s mod_summary >>=  \interpreted -> 
+                           return (showModMsg (hscTarget(hsc_dflags hsc_env)) interpreted mod_summary)
+
+isModuleInterpreted :: Session -> ModSummary -> IO Bool
+isModuleInterpreted s mod_summary = withSession s $ \hsc_env -> 
   case lookupUFM (hsc_HPT hsc_env) (ms_mod_name mod_summary) of
        Nothing       -> panic "missing linkable"
   case lookupUFM (hsc_HPT hsc_env) (ms_mod_name mod_summary) of
        Nothing       -> panic "missing linkable"
-       Just mod_info -> return (showModMsg (hscTarget (hsc_dflags hsc_env)) (not obj_linkable) mod_summary)
+       Just mod_info -> return (not obj_linkable)
                      where
                         obj_linkable = isObjectLinkable (expectJust "showModule" (hm_linkable mod_info))
 
                      where
                         obj_linkable = isObjectLinkable (expectJust "showModule" (hm_linkable mod_info))
 
+-----------------------------------------------------------------------------
+-- Breakpoint handlers
+
+getBreakpointHandler :: Session -> IO (Maybe (BkptHandler Module))
+getBreakpointHandler session = getSessionDynFlags session >>= return . bkptHandler
+setBreakpointHandler :: Session -> BkptHandler Module -> IO ()
+setBreakpointHandler session handler = do
+  dflags <- getSessionDynFlags session
+  setSessionDynFlags session dflags{ bkptHandler = Just handler }
+  let linkEnv =   [ ( breakpointJumpName
+                    , unsafeCoerce# (jumpFunction session handler))
+                  , ( breakpointCondJumpName
+                    , unsafeCoerce# (jumpCondFunction session handler))
+                  , ( breakpointAutoJumpName 
+                    , unsafeCoerce# (jumpAutoFunction session handler))
+                  ]
+  writeIORef v_bkptLinkEnv linkEnv
+  dflags <- getSessionDynFlags session
+  reinstallBreakpointHandlers session
+
+reinstallBreakpointHandlers :: Session -> IO ()
+reinstallBreakpointHandlers session = do
+  dflags <- getSessionDynFlags session
+  let mode = ghcMode dflags
+  when (ghcLink dflags == LinkInMemory) $ do
+    linkEnv <- readIORef v_bkptLinkEnv
+    initDynLinker dflags 
+    extendLinkEnv linkEnv
+
+-----------------------------------------------------------------------
+-- Jump functions
+
+type SiteInfo = (String, SiteNumber)
+jumpFunction, jumpAutoFunction  :: Session -> BkptHandler Module -> SiteInfo -> (Int, [Opaque], String) -> b -> b
+jumpCondFunction  :: Session -> BkptHandler Module -> SiteInfo -> (Int, [Opaque], String) -> Bool -> b -> b
+jumpFunctionM :: Session -> BkptHandler a ->  BkptLocation a -> (Int, [Opaque], String) -> b -> IO b
+
+jumpCondFunction _ _ _ _ False b = b
+jumpCondFunction session handler site args True b
+    = jumpFunction session handler site args b
+
+jumpFunction session handler siteInfo args b 
+    | site <- mkSite siteInfo
+    = unsafePerformIO $ jumpFunctionM session handler site args b
+
+jumpFunctionM session handler site (I# idsPtr, wrapped_hValues, locmsg) b = 
+      do 
+         ids <- deRefStablePtr (castPtrToStablePtr (Ptr (int2Addr# idsPtr)))
+         let hValues = unsafeCoerce# b : [unsafeCoerce# hv | O hv <- wrapped_hValues]
+         handleBreakpoint handler session (zip ids hValues) site locmsg b
+
+jumpAutoFunction session handler siteInfo args b 
+    | site <- mkSite siteInfo
+    = unsafePerformIO $ do
+         break <- isAutoBkptEnabled handler session site 
+         if break 
+            then jumpFunctionM session handler site args b
+            else return b
+
+jumpStepByStepFunction session handler siteInfo args b 
+    | site <- mkSite siteInfo
+    = unsafePerformIO $ do
+          jumpFunctionM session handler site args b
+
+mkSite :: SiteInfo -> BkptLocation Module
+mkSite ( modName, sitenum) =
+  (mkModule mainPackageId (mkModuleName modName), sitenum)
+
+obtainTerm1 :: Session -> Bool -> Maybe Type -> a -> IO Term
+obtainTerm1 sess force mb_ty x = withSession sess $ \hsc_env -> cvObtainTerm hsc_env force mb_ty (unsafeCoerce# x)
+
+obtainTerm :: Session -> Bool -> Id -> IO (Maybe Term)
+obtainTerm sess force id = withSession sess $ \hsc_env -> do
+              mb_v <- getHValue (varName id) 
+              case mb_v of
+                Just v  -> fmap Just$ cvObtainTerm hsc_env force (Just$ idType id) v
+                Nothing -> return Nothing
+
 #endif /* GHCI */
 #endif /* GHCI */