[project @ 2000-12-07 08:28:05 by simonpj]
[ghc-hetmet.git] / ghc / compiler / basicTypes / Name.lhs
index 14691d6..aef8355 100644 (file)
 %
-% (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
+% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
 \section[Name]{@Name@: to transmit name info from renamer to typechecker}
 
 \begin{code}
-#include "HsVersions.h"
-
 module Name (
-       Module(..),
-
-       RdrName(..),
-       isUnqual,
-       isQual,
-       isConopRdr,
-       appendRdr,
-       rdrToOrig,
-       showRdr,
-       cmpRdr,
-
-       Name,
-       Provenance,
-       mkLocalName, isLocalName, 
-       mkTopLevName, mkImportedName,
-       mkImplicitName, isImplicitName,
-       mkBuiltinName,
-
-       NamedThing(..), -- class
-       ExportFlag(..), isExported,
-
-       nameUnique,
-       nameOrigName,
-       nameOccName,
-       nameExportFlag,
-       nameSrcLoc,
-       isLocallyDefinedName,
-       isPreludeDefinedName,
-
-       getOrigName, getOccName, getExportFlag,
-       getSrcLoc, isLocallyDefined, isPreludeDefined,
-       getLocalName, getOrigNameRdr, ltLexical,
-
-       isOpLexeme, pprOp, pprNonOp,
-       isConop, isAconop, isAvarid, isAvarop
+       -- Re-export the OccName stuff
+       module OccName,
+
+       -- The Name type
+       Name,                                   -- Abstract
+       mkLocalName, mkSysLocalName, mkCCallName,
+       mkIPName,
+       mkGlobalName, mkKnownKeyGlobal, mkWiredInName,
+
+       nameUnique, setNameUnique,
+       nameOccName, nameModule, nameModule_maybe,
+       setNameOcc, nameRdrName, setNameModuleAndLoc, 
+       toRdrName, hashName, 
+       globaliseName, localiseName,
+
+       nameSrcLoc, nameIsLocallyDefined, isDllName, nameIsFrom, nameIsLocalOrFrom,
+
+       isSystemName, isLocalName, isGlobalName, isExternallyVisibleName,
+       isTyVarName,
+       
+       -- Environment
+       NameEnv, mkNameEnv,
+       emptyNameEnv, unitNameEnv, nameEnvElts, 
+       extendNameEnv_C, extendNameEnv, foldNameEnv, filterNameEnv,
+       plusNameEnv, plusNameEnv_C, extendNameEnv, extendNameEnvList,
+       lookupNameEnv, lookupNameEnv_NF, delFromNameEnv, elemNameEnv, 
+
+
+       -- Class NamedThing and overloaded friends
+       NamedThing(..),
+       getSrcLoc, getOccString, toRdrName,
+       isFrom, isLocalOrFrom
     ) where
 
-import Ubiq
+#include "HsVersions.h"
 
-import CStrings                ( identToC, cSEP )
-import Outputable      ( Outputable(..) )
-import PprStyle                ( PprStyle(..), codeStyle )
-import Pretty
-import PrelMods                ( pRELUDE )
-import SrcLoc          ( mkBuiltinSrcLoc, mkUnknownSrcLoc )
-import Unique          ( pprUnique, Unique )
-import Util            ( thenCmp, _CMP_STRING_, panic )
+import OccName         -- All of it
+import Module          ( Module, moduleName, mkVanillaModule, isHomeModule )
+import RdrName         ( RdrName, mkRdrOrig, mkRdrUnqual, rdrNameOcc, rdrNameModule )
+import CmdLineOpts     ( opt_Static )
+import SrcLoc          ( builtinSrcLoc, noSrcLoc, SrcLoc )
+import Unique          ( Unique, Uniquable(..), u2i, pprUnique, pprUnique10 )
+import FastTypes
+import Maybes          ( expectJust )
+import UniqFM
+import Outputable
 \end{code}
 
 %************************************************************************
 %*                                                                     *
-\subsection[RdrName]{The @RdrName@ datatype; names read from files}
+\subsection[Name-datatype]{The @Name@ datatype, and name construction}
 %*                                                                     *
 %************************************************************************
-
 \begin{code}
-type Module = FAST_STRING
+data Name = Name {
+               n_sort :: NameSort,     -- What sort of name it is
+               n_occ  :: OccName,      -- Its occurrence name
+               n_uniq :: Unique,
+               n_loc  :: SrcLoc        -- Definition site
+           }
+
+data NameSort
+  = Global Module      -- (a) TyCon, Class, their derived Ids, dfun Id
+                       -- (b) Imported Id
+                       -- (c) Top-level Id in the original source, even if
+                       --      locally defined
+
+  | Local              -- A user-defined Id or TyVar
+                       -- defined in the module being compiled
+
+  | System             -- A system-defined Id or TyVar.  Typically the
+                       -- OccName is very uninformative (like 's')
+\end{code}
 
-data RdrName  = Unqual FAST_STRING
-              | Qual Module FAST_STRING
+Notes about the NameSorts:
 
-isUnqual (Unqual _) = True
-isUnqual (Qual _ _) = False
+1.  Initially, top-level Ids (including locally-defined ones) get Global names, 
+    and all other local Ids get Local names
 
-isQual (Unqual _) = False
-isQual (Qual _ _) = True
+2.  Things with a @Global@ name are given C static labels, so they finally
+    appear in the .o file's symbol table.  They appear in the symbol table
+    in the form M.n.  If originally-local things have this property they
+    must be made @Global@ first.
 
-isConopRdr (Unqual n) = isConop n
-isConopRdr (Qual m n) = isConop n
+3.  In the tidy-core phase, a Global that is not visible to an importer
+    is changed to Local, and a Local that is visible is changed to Global
 
-appendRdr (Unqual n) str = Unqual (n _APPEND_ str)
-appendRdr (Qual m n) str = Qual m (n _APPEND_ str)
+4.  A System Name differs in the following ways:
+       a) has unique attached when printing dumps
+       b) unifier eliminates sys tyvars in favour of user provs where possible
 
-rdrToOrig (Unqual n) = (pRELUDE, n)
-rdrToOrig (Qual m n) = (m, n)
+    Before anything gets printed in interface files or output code, it's
+    fed through a 'tidy' processor, which zaps the OccNames to have
+    unique names; and converts all sys-locals to user locals
+    If any desugarer sys-locals have survived that far, they get changed to
+    "ds1", "ds2", etc.
 
-cmpRdr (Unqual n1)  (Unqual n2)  = _CMP_STRING_ n1 n2
-cmpRdr (Unqual n1)  (Qual m2 n2) = LT_
-cmpRdr (Qual m1 n1) (Unqual n2)  = GT_
-cmpRdr (Qual m1 n1) (Qual m2 n2) = thenCmp (_CMP_STRING_ m1 m2) (_CMP_STRING_ n1 n2) 
+\begin{code}
+nameUnique             :: Name -> Unique
+nameOccName            :: Name -> OccName 
+nameModule             :: Name -> Module
+nameSrcLoc             :: Name -> SrcLoc
 
-instance Eq RdrName where
-    a == b = case (a `cmp` b) of { EQ_ -> True;  _ -> False }
-    a /= b = case (a `cmp` b) of { EQ_ -> False; _ -> True }
+nameUnique  name = n_uniq name
+nameOccName name = n_occ  name
+nameSrcLoc  name = n_loc  name
 
-instance Ord RdrName where
-    a <= b = case (a `cmp` b) of { LT_ -> True;         EQ_ -> True;  GT__ -> False }
-    a <         b = case (a `cmp` b) of { LT_ -> True;  EQ_ -> False; GT__ -> False }
-    a >= b = case (a `cmp` b) of { LT_ -> False; EQ_ -> True;  GT__ -> True  }
-    a >         b = case (a `cmp` b) of { LT_ -> False; EQ_ -> False; GT__ -> True  }
+nameModule (Name { n_sort = Global mod }) = mod
+nameModule name                                  = pprPanic "nameModule" (ppr name)
 
-instance Ord3 RdrName where
-    cmp = cmpRdr
+nameModule_maybe (Name { n_sort = Global mod }) = Just mod
+nameModule_maybe name                          = Nothing
+\end{code}
 
-instance NamedThing RdrName where
-    -- We're sorta faking it here
-    getName rdr_name
-      = Global u rdr_name prov ex [rdr_name]
-      where
-       u    = panic "NamedThing.RdrName:Unique"
-       prov = panic "NamedThing.RdrName:Provenance"
-       ex   = panic "NamedThing.RdrName:ExportFlag"
+\begin{code}
+nameIsLocallyDefined   :: Name -> Bool
+nameIsFrom             :: Module -> Name -> Bool
+nameIsLocalOrFrom      :: Module -> Name -> Bool
+isLocalName            :: Name -> Bool         -- Not globals
+isGlobalName           :: Name -> Bool
+isSystemName           :: Name -> Bool
+isExternallyVisibleName :: Name -> Bool
+
+isGlobalName (Name {n_sort = Global _}) = True
+isGlobalName other                     = False
+
+isLocalName name = not (isGlobalName name)
 
-instance Outputable RdrName where
-    ppr sty (Unqual n) = pp_name sty n
-    ppr sty (Qual m n) = ppBeside (pp_mod sty m) (pp_name sty n)
+nameIsLocallyDefined name = isLocalName name
 
-pp_mod PprInterface        m = ppNil
-pp_mod PprForC             m = ppBesides [identToC m, ppPStr cSEP]
-pp_mod (PprForAsm False _) m = ppBesides [identToC m, ppPStr cSEP]
-pp_mod (PprForAsm True  _) m = ppBesides [ppPStr cSEP, identToC m, ppPStr cSEP]
-pp_mod _                   m = ppBesides [ppPStr m, ppChar '.']
+nameIsLocalOrFrom from (Name {n_sort = Global mod}) = mod == from
+nameIsLocalOrFrom from other                       = True
 
-pp_name sty n | codeStyle sty = identToC n
-              | otherwise     = ppPStr n             
+nameIsFrom from (Name {n_sort = Global mod}) = mod == from
+nameIsFrom from other                       = pprPanic "nameIsFrom" (ppr other)
 
-showRdr sty rdr = ppShow 100 (ppr sty rdr)
+-- Global names are by definition those that are visible
+-- outside the module, *as seen by the linker*.  Externally visible
+-- does not mean visible at the source level
+isExternallyVisibleName name = isGlobalName name
+
+isSystemName (Name {n_sort = System}) = True
+isSystemName other                   = False
 \end{code}
 
+
 %************************************************************************
 %*                                                                     *
-\subsection[Name-datatype]{The @Name@ datatype}
+\subsection{Making names}
 %*                                                                     *
 %************************************************************************
 
 \begin{code}
-data Name
-  = Local    Unique
-             FAST_STRING
-             SrcLoc
-
-  | Global   Unique
-             RdrName      -- original name; Unqual => prelude
-             Provenance   -- where it came from
-             ExportFlag   -- is it exported?
-             [RdrName]    -- ordered occurrence names (usually just one);
-                         -- first may be *un*qual.
-
-data Provenance
-  = LocalDef SrcLoc       -- locally defined; give its source location
-
-  | Imported SrcLoc       -- imported; give the *original* source location
-         --  [SrcLoc]     -- any import source location(s)
-
-  | Implicit
-  | Builtin
+mkLocalName :: Unique -> OccName -> SrcLoc -> Name
+mkLocalName uniq occ loc = Name { n_uniq = uniq, n_sort = Local, n_occ = occ, n_loc = loc }
+       -- NB: You might worry that after lots of huffing and
+       -- puffing we might end up with two local names with distinct
+       -- uniques, but the same OccName.  Indeed we can, but that's ok
+       --      * the insides of the compiler don't care: they use the Unique
+       --      * when printing for -ddump-xxx you can switch on -dppr-debug to get the
+       --        uniques if you get confused
+       --      * for interface files we tidyCore first, which puts the uniques
+       --        into the print name (see setNameVisibility below)
+
+mkGlobalName :: Unique -> Module -> OccName -> SrcLoc -> Name
+mkGlobalName uniq mod occ loc = Name { n_uniq = uniq, n_sort = Global mod,
+                                      n_occ = occ, n_loc = loc }
+
+mkKnownKeyGlobal :: RdrName -> Unique -> Name
+mkKnownKeyGlobal rdr_name uniq
+  = mkGlobalName uniq (mkVanillaModule (rdrNameModule rdr_name))
+                     (rdrNameOcc rdr_name)
+                     builtinSrcLoc
+
+mkWiredInName :: Module -> OccName -> Unique -> Name
+mkWiredInName mod occ uniq = mkGlobalName uniq mod occ builtinSrcLoc
+
+mkSysLocalName :: Unique -> UserFS -> Name
+mkSysLocalName uniq fs = Name { n_uniq = uniq, n_sort = System, 
+                               n_occ = mkVarOcc fs, n_loc = noSrcLoc }
+
+mkCCallName :: Unique -> EncodedString -> Name
+       -- The encoded string completely describes the ccall
+mkCCallName uniq str =  Name { n_uniq = uniq, n_sort = Local, 
+                              n_occ = mkCCallOcc str, n_loc = noSrcLoc }
+
+mkIPName :: Unique -> OccName -> Name
+mkIPName uniq occ
+  = Name { n_uniq = uniq,
+          n_sort = Local,
+          n_occ  = occ,
+          n_loc = noSrcLoc }
 \end{code}
 
 \begin{code}
-mkLocalName = Local
+-- When we renumber/rename things, we need to be
+-- able to change a Name's Unique to match the cached
+-- one in the thing it's the name of.  If you know what I mean.
+setNameUnique name uniq = name {n_uniq = uniq}
+
+setNameOcc :: Name -> OccName -> Name
+setNameOcc name occ = name {n_occ = occ}
+
+globaliseName :: Name -> Module -> Name
+globaliseName n mod = n { n_sort = Global mod }
+                               
+localiseName :: Name -> Name
+localiseName n = n { n_sort = Local }
+                               
+setNameModuleAndLoc :: Name -> Module -> SrcLoc -> Name
+setNameModuleAndLoc name mod loc = name {n_sort = set (n_sort name), n_loc = loc}
+                      where
+                        set (Global _) = Global mod
+\end{code}
 
-mkTopLevName   u orig locn exp occs = Global u orig (LocalDef locn) exp occs
-mkImportedName u orig locn exp occs = Global u orig (Imported locn) exp occs
 
-mkImplicitName :: Unique -> RdrName -> Name
-mkImplicitName u o = Global u o Implicit NotExported []
+%************************************************************************
+%*                                                                     *
+\subsection{Predicates and selectors}
+%*                                                                     *
+%************************************************************************
 
-mkBuiltinName :: Unique -> Module -> FAST_STRING -> Name
-mkBuiltinName u m n = Global u (Unqual n) Builtin NotExported []
+\begin{code}
+hashName :: Name -> Int
+hashName name = iBox (u2i (nameUnique name))
 
-       -- ToDo: what about module ???
-       -- ToDo: exported when compiling builtin ???
 
-isLocalName (Local _ _ _) = True
-isLocalName _          = False
+nameRdrName :: Name -> RdrName
+-- Makes a qualified name for top-level (Global) names, whether locally defined or not
+-- and an unqualified name just for Locals
+nameRdrName (Name { n_occ = occ, n_sort = Global mod }) = mkRdrOrig (moduleName mod) occ
+nameRdrName (Name { n_occ = occ })                     = mkRdrUnqual occ
 
-isImplicitName (Global _ _ Implicit _ _) = True
-isImplicitName _                        = False
+isDllName :: Name -> Bool
+       -- Does this name refer to something in a different DLL?
+isDllName nm = not opt_Static &&
+              not (isLocalName nm) &&                          -- isLocalName test needed 'cos
+              not (isHomeModule (nameModule nm))       -- nameModule won't work on local names
 
-isBuiltinName  (Global _ _ Builtin  _ _) = True
-isBuiltinName  _                        = False
-\end{code}
 
 
+isTyVarName :: Name -> Bool
+isTyVarName name = isTvOcc (nameOccName name)
+\end{code}
+
 
 %************************************************************************
 %*                                                                     *
@@ -189,128 +259,117 @@ isBuiltinName  _                         = False
 %************************************************************************
 
 \begin{code}
-cmpName n1 n2 = c n1 n2
-  where
-    c (Local    u1 _ _)            (Local    u2 _ _)     = cmp u1 u2
-    c (Global   u1 _ _ _ _) (Global   u2 _ _ _ _) = cmp u1 u2
-
-    c other_1 other_2          -- the tags *must* be different
-      = let tag1 = tag_Name n1
-           tag2 = tag_Name n2
-       in
-       if tag1 _LT_ tag2 then LT_ else GT_
-
-    tag_Name (Local    _ _ _)    = (ILIT(1) :: FAST_INT)
-    tag_Name (Global   _ _ _ _ _) = ILIT(2)
+cmpName n1 n2 = n_uniq n1 `compare` n_uniq n2
 \end{code}
 
 \begin{code}
 instance Eq Name where
-    a == b = case (a `cmp` b) of { EQ_ -> True;  _ -> False }
-    a /= b = case (a `cmp` b) of { EQ_ -> False; _ -> True }
+    a == b = case (a `compare` b) of { EQ -> True;  _ -> False }
+    a /= b = case (a `compare` b) of { EQ -> False; _ -> True }
 
 instance Ord Name where
-    a <= b = case (a `cmp` b) of { LT_ -> True;         EQ_ -> True;  GT__ -> False }
-    a <         b = case (a `cmp` b) of { LT_ -> True;  EQ_ -> False; GT__ -> False }
-    a >= b = case (a `cmp` b) of { LT_ -> False; EQ_ -> True;  GT__ -> True  }
-    a >         b = case (a `cmp` b) of { LT_ -> False; EQ_ -> False; GT__ -> True  }
-
-instance Ord3 Name where
-    cmp = cmpName
+    a <= b = case (a `compare` b) of { LT -> True;  EQ -> True;  GT -> False }
+    a <         b = case (a `compare` b) of { LT -> True;  EQ -> False; GT -> False }
+    a >= b = case (a `compare` b) of { LT -> False; EQ -> True;  GT -> True  }
+    a >         b = case (a `compare` b) of { LT -> False; EQ -> False; GT -> True  }
+    compare a b = cmpName a b
 
 instance Uniquable Name where
-    uniqueOf = nameUnique
+    getUnique = nameUnique
 
 instance NamedThing Name where
     getName n = n
 \end{code}
 
-\begin{code}
-nameUnique (Local    u _ _)     = u
-nameUnique (Global   u _ _ _ _) = u
-
-nameOrigName (Local    _ n _)       = (panic "NamedThing.Local.nameOrigName", n)
-nameOrigName (Global   _ orig _ _ _) = rdrToOrig orig
-
-nameOccName (Local    _ n _)          = Unqual n
-nameOccName (Global   _ orig _ _ []  ) = orig
-nameOccName (Global   _ orig _ _ occs) = head occs
-
-nameExportFlag (Local    _ _ _)              = NotExported
-nameExportFlag (Global   _ _ _ exp _) = exp
 
-nameSrcLoc (Local  _ _ loc)                  = loc
-nameSrcLoc (Global _ _ (LocalDef loc) _ _) = loc
-nameSrcLoc (Global _ _ (Imported loc) _ _) = loc
-nameSrcLoc (Global _ _ Implicit       _ _) = mkUnknownSrcLoc
-nameSrcLoc (Global _ _ Builtin        _ _) = mkBuiltinSrcLoc
-
-isLocallyDefinedName (Local  _ _ _)               = True
-isLocallyDefinedName (Global _ _ (LocalDef _) _ _) = True
-isLocallyDefinedName (Global _ _ (Imported _) _ _) = False
-isLocallyDefinedName (Global _ _ Implicit     _ _) = False
-isLocallyDefinedName (Global _ _ Builtin      _ _) = False
-
-isPreludeDefinedName (Local    _ n _)        = False
-isPreludeDefinedName (Global   _ orig _ _ _) = isUnqual orig
-\end{code}
+%************************************************************************
+%*                                                                     *
+\subsection{Name environment}
+%*                                                                     *
+%************************************************************************
 
 \begin{code}
-instance Outputable Name where
-#ifdef DEBUG
-    ppr PprDebug (Local    u n _)     = pp_debug u (ppPStr n)
-    ppr PprDebug (Global   u o _ _ _) = pp_debug u (ppr PprDebug o)
-#endif
-    ppr sty        (Local    u n _)             = pp_name sty n
-    ppr PprForUser (Global   u o _ _ []  )      = ppr PprForUser o
-    ppr PprForUser (Global   u o _ _ occs)      = ppr PprForUser (head occs)
-    ppr PprShowAll (Global   u o prov exp occs) = pp_all o prov exp occs
-    ppr sty        (Global   u o _ _ _)         = ppr sty o
-
-pp_debug uniq thing
-  = ppBesides [thing, ppStr "{-", pprUnique uniq, ppStr "-}" ]
-
-pp_all orig prov exp occs
-  = ppBesides [ppr PprShowAll orig, ppr PprShowAll occs, pp_prov prov, pp_exp exp]
-
-pp_exp NotExported = ppNil
-pp_exp ExportAll   = ppPStr SLIT("/EXP(..)")
-pp_exp ExportAbs   = ppPStr SLIT("/EXP")
-
-pp_prov Implicit = ppPStr SLIT("/IMPLICIT")
-pp_prov Builtin  = ppPStr SLIT("/BUILTIN")
-pp_prov _        = ppNil
+type NameEnv a = UniqFM a      -- Domain is Name
+
+emptyNameEnv            :: NameEnv a
+mkNameEnv       :: [(Name,a)] -> NameEnv a
+nameEnvElts             :: NameEnv a -> [a]
+extendNameEnv_C  :: (a->a->a) -> NameEnv a -> Name -> a -> NameEnv a
+extendNameEnv           :: NameEnv a -> Name -> a -> NameEnv a
+plusNameEnv             :: NameEnv a -> NameEnv a -> NameEnv a
+plusNameEnv_C           :: (a->a->a) -> NameEnv a -> NameEnv a -> NameEnv a
+extendNameEnvList:: NameEnv a -> [(Name,a)] -> NameEnv a
+delFromNameEnv          :: NameEnv a -> Name -> NameEnv a
+elemNameEnv             :: Name -> NameEnv a -> Bool
+unitNameEnv             :: Name -> a -> NameEnv a
+lookupNameEnv           :: NameEnv a -> Name -> Maybe a
+lookupNameEnv_NF :: NameEnv a -> Name -> a
+mapNameEnv      :: (a->b) -> NameEnv a -> NameEnv b
+foldNameEnv     :: (a -> b -> b) -> b -> NameEnv a -> b
+filterNameEnv   :: (elt -> Bool) -> NameEnv elt -> NameEnv elt
+
+emptyNameEnv            = emptyUFM
+foldNameEnv     = foldUFM
+mkNameEnv       = listToUFM
+nameEnvElts             = eltsUFM
+extendNameEnv_C  = addToUFM_C
+extendNameEnv           = addToUFM
+plusNameEnv             = plusUFM
+plusNameEnv_C           = plusUFM_C
+extendNameEnvList= addListToUFM
+delFromNameEnv          = delFromUFM
+elemNameEnv             = elemUFM
+mapNameEnv      = mapUFM
+unitNameEnv             = unitUFM
+filterNameEnv   = filterUFM
+
+lookupNameEnv                 = lookupUFM
+lookupNameEnv_NF env n = expectJust "lookupNameEnv_NF" (lookupUFM env n)
 \end{code}
 
+
 %************************************************************************
 %*                                                                     *
-\subsection[ExportFlag-datatype]{The @ExportFlag@ datatype}
+\subsection{Pretty printing}
 %*                                                                     *
 %************************************************************************
 
-The export flag @ExportAll@ means `export all there is', so there are
-times when it is attached to a class or data type which has no
-ops/constructors (if the class/type was imported abstractly).  In
-fact, @ExportAll@ is attached to everything except to classes/types
-which are being {\em exported} abstractly, regardless of how they were
-imported.
-
 \begin{code}
-data ExportFlag
-  = ExportAll          -- export with all constructors/methods
-  | ExportAbs          -- export abstractly
-  | NotExported
-
-isExported a
-  = case (getExportFlag a) of
-      NotExported -> False
-      _                  -> True
-
-#ifdef USE_ATTACK_PRAGMAS
-{-# SPECIALIZE isExported :: Class -> Bool #-}
-{-# SPECIALIZE isExported :: Id -> Bool #-}
-{-# SPECIALIZE isExported :: TyCon -> Bool #-}
-#endif
+instance Outputable Name where
+       -- When printing interfaces, all Locals have been given nice print-names
+    ppr name = pprName name
+
+pprName name@(Name {n_sort = sort, n_uniq = uniq, n_occ = occ})
+  = getPprStyle $ \ sty ->
+    case sort of
+      Global mod -> pprGlobal sty name uniq mod occ
+      System     -> pprSysLocal sty uniq occ
+      Local      -> pprLocal sty uniq occ
+
+pprGlobal sty name uniq mod occ
+  | codeStyle sty        = ppr (moduleName mod) <> char '_' <> pprOccName occ
+
+  | debugStyle sty       = ppr (moduleName mod) <> dot <> pprOccName occ <> 
+                           text "{-" <> pprUnique uniq <> text "-}"
+
+  | unqualStyle sty name = pprOccName occ
+  | otherwise           = ppr (moduleName mod) <> dot <> pprOccName occ
+
+pprLocal sty uniq occ
+  | codeStyle sty  = pprUnique uniq
+  | debugStyle sty = pprOccName occ <> 
+                    text "{-" <> pprUnique10 uniq <> text "-}"
+  | otherwise      = pprOccName occ    -- User and Iface styles
+
+-- Like Local, except that we only omit the unique in Iface style
+pprSysLocal sty uniq occ
+  | codeStyle sty  = pprUnique uniq
+  | ifaceStyle sty = pprOccName occ    -- The tidy phase has ensured that OccNames
+                                       -- are enough
+  | otherwise     = pprOccName occ <> char '_' <> pprUnique uniq
+                               -- If the tidy phase hasn't run, the OccName
+                               -- is unlikely to be informative (like 's'),
+                               -- so print the unique
 \end{code}
 
 %************************************************************************
@@ -321,131 +380,23 @@ isExported a
 
 \begin{code}
 class NamedThing a where
-    getName :: a -> Name
+    getOccName :: a -> OccName
+    getName    :: a -> Name
+
+    getOccName n = nameOccName (getName n)     -- Default method
 \end{code}
 
 \begin{code}
-getOrigName        :: NamedThing a => a -> (Module, FAST_STRING)
-getOccName         :: NamedThing a => a -> RdrName
-getExportFlag      :: NamedThing a => a -> ExportFlag
 getSrcLoc          :: NamedThing a => a -> SrcLoc
-isLocallyDefined    :: NamedThing a => a -> Bool
-isPreludeDefined    :: NamedThing a => a -> Bool
+getOccString       :: NamedThing a => a -> String
+toRdrName          :: NamedThing a => a -> RdrName
+isFrom             :: NamedThing a => Module -> a -> Bool
+isLocalOrFrom      :: NamedThing a => Module -> a -> Bool
 
-getOrigName        = nameOrigName         . getName
-getOccName         = nameOccName          . getName
-getExportFlag      = nameExportFlag       . getName
 getSrcLoc          = nameSrcLoc           . getName
-isLocallyDefined    = isLocallyDefinedName . getName
-isPreludeDefined    = isPreludeDefinedName . getName
-
-getLocalName :: (NamedThing a) => a -> FAST_STRING
-getLocalName = snd . getOrigName
-
-getOrigNameRdr :: (NamedThing a) => a -> RdrName
-getOrigNameRdr n | isPreludeDefined n = Unqual str
-                | otherwise          = Qual mod str
-  where
-    (mod,str) = getOrigName n
-\end{code}
-
-@ltLexical@ is used for sorting things into lexicographical order, so
-as to canonicalize interfaces.  [Regular @(<)@ should be used for fast
-comparison.]
-
-\begin{code}
-a `ltLexical` b
-  = BIND isLocallyDefined a    _TO_ a_local ->
-    BIND isLocallyDefined b    _TO_ b_local ->
-    BIND getOrigName a         _TO_ (a_mod, a_name) ->
-    BIND getOrigName b         _TO_ (b_mod, b_name) ->
-    if a_local || b_local then
-       a_name < b_name -- can't compare module names
-    else
-       case _CMP_STRING_ a_mod b_mod of
-        LT_  -> True
-        EQ_  -> a_name < b_name
-        GT__ -> False
-    BEND BEND BEND BEND
-
-#ifdef USE_ATTACK_PRAGMAS
-{-# SPECIALIZE ltLexical :: Class -> Class -> Bool #-}
-{-# SPECIALIZE ltLexical :: Id -> Id -> Bool #-}
-{-# SPECIALIZE ltLexical :: TyCon -> TyCon -> Bool #-}
-#endif
-\end{code}
-
-These functions test strings to see if they fit the lexical categories
-defined in the Haskell report.  Normally applied as in e.g. @isConop
-(getLocalName foo)@
-
-\begin{code}
-isConop, isAconop, isAvarid, isAvarop :: FAST_STRING -> Bool
-
-isConop cs
-  | _NULL_ cs  = False
-  | c == '_'   = isConop (_TAIL_ cs)           -- allow for leading _'s
-  | otherwise  = isUpper c || c == ':' 
-                 || c == '[' || c == '('       -- [] () and (,,) come is as Conop strings !!!
-                 || isUpperISO c
-  where                                        
-    c = _HEAD_ cs
-
-isAconop cs
-  | _NULL_ cs  = False
-  | otherwise  = c == ':'
-  where
-    c = _HEAD_ cs
-
-isAvarid cs
-  | _NULL_ cs   = False
-  | c == '_'    = isAvarid (_TAIL_ cs) -- allow for leading _'s
-  | isLower c   = True
-  | isLowerISO c = True
-  | otherwise    = False
-  where
-    c = _HEAD_ cs
-
-isAvarop cs
-  | _NULL_ cs                      = False
-  | isLower c                      = False
-  | isUpper c                      = False
-  | c `elem` "!#$%&*+./<=>?@\\^|~-" = True
-  | isSymbolISO c                  = True
-  | otherwise                      = False
-  where
-    c = _HEAD_ cs
-
-isSymbolISO c = ord c `elem` (0xd7 : 0xf7 : [0xa1 .. 0xbf])
-isUpperISO  c = 0xc0 <= oc && oc <= 0xde && oc /= 0xd7 where oc = ord c
-isLowerISO  c = 0xdf <= oc && oc <= 0xff && oc /= 0xf7 where oc = ord c
+getOccString       = occNameString        . getOccName
+toRdrName          = nameRdrName          . getName
+isFrom mod x       = nameIsFrom mod (getName x)
+isLocalOrFrom mod x = nameIsLocalOrFrom mod ( getName x)
 \end{code}
 
-And one ``higher-level'' interface to those:
-
-\begin{code}
-isOpLexeme :: NamedThing a => a -> Bool
-
-isOpLexeme v
-  = let str = snd (getOrigName v) in isAvarop str || isAconop str
-
--- print `vars`, (op) correctly
-pprOp, pprNonOp :: (NamedThing name, Outputable name) => PprStyle -> name -> Pretty
-
-pprOp sty var
-  = if isOpLexeme var
-    then ppr sty var
-    else ppBesides [ppChar '`', ppr sty var, ppChar '`']
-
-pprNonOp sty var
-  = if isOpLexeme var
-    then ppBesides [ppLparen, ppr sty var, ppRparen]
-    else ppr sty var
-
-#ifdef USE_ATTACK_PRAGMAS
-{-# SPECIALIZE isOpLexeme :: Id -> Bool #-}
-{-# SPECIALIZE pprNonOp :: PprStyle -> Id -> Pretty #-}
-{-# SPECIALIZE pprNonOp :: PprStyle -> TyCon -> Pretty #-}
-{-# SPECIALIZE pprOp :: PprStyle -> Id -> Pretty #-}
-#endif
-\end{code}