[project @ 1998-12-02 13:17:09 by simonm]
[ghc-hetmet.git] / ghc / compiler / basicTypes / Name.lhs
index 79ffa10..5fc667c 100644 (file)
@@ -1,51 +1,53 @@
 %
-% (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 (
        -- Re-export the Module type
-       SYN_IE(Module),
+       Module,
        pprModule, moduleString,
 
+       -- The basic form of names
+       isLexCon, isLexVar, isLexId, isLexSym,
+       isLexConId, isLexConSym, isLexVarId, isLexVarSym,
+       mkTupNameStr, mkUbxTupNameStr, isLowerISO, isUpperISO,
+
        -- The OccName type
-       OccName(..),
+       OccName(..), varOcc, 
        pprOccName, occNameString, occNameFlavour, 
        isTvOcc, isTCOcc, isVarOcc, prefixOccName,
-       uniqToOccName,
 
        -- The Name type
        Name,                                   -- Abstract
        mkLocalName, mkSysLocalName, 
 
-       mkCompoundName, mkGlobalName, mkInstDeclName,
+       mkCompoundName, mkGlobalName,
 
        mkWiredInIdName,   mkWiredInTyConName,
        maybeWiredInIdName, maybeWiredInTyConName,
        isWiredInName,
 
        nameUnique, changeUnique, setNameProvenance, getNameProvenance,
-       setNameVisibility,
-       nameOccName, nameString, nameModule,
+       setNameVisibility, mkNameVisible,
+       nameOccName, nameModule,
 
        isExportedName, nameSrcLoc,
        isLocallyDefinedName,
 
-       isLocalName, 
+       isSysLocalName, isLocalName, isGlobalName, isExternallyVisibleName,
 
         pprNameProvenance,
 
-       -- Sets of Names
-       SYN_IE(NameSet),
-       emptyNameSet, unitNameSet, mkNameSet, unionNameSets, unionManyNameSets,
-       minusNameSet, elemNameSet, nameSetToList, addOneToNameSet, addListToNameSet, isEmptyNameSet,
+       -- Special Names
+       dictNamePrefix, mkSuperDictSelName, mkWorkerName,
+       mkDefaultMethodName, mkClassTyConStr, mkClassDataConStr,
 
        -- Misc
        Provenance(..), pprProvenance,
-       ExportFlag(..),
+       ExportFlag(..), 
+       PrintUnqualified,
 
        -- Class NamedThing and overloaded friends
        NamedThing(..),
@@ -53,29 +55,97 @@ module Name (
        getSrcLoc, isLocallyDefined, getOccString
     ) where
 
-IMP_Ubiq()
-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ <= 201
-IMPORT_DELOOPER(TyLoop)        ( GenId, Id(..), TyCon )                        -- Used inside Names
-#else
-import {-# SOURCE #-} Id    ( Id )
+#include "HsVersions.h"
+
+import {-# SOURCE #-} Var   ( Id )
 import {-# SOURCE #-} TyCon ( TyCon )
-#endif
-
-import CStrings                ( identToC, modnameToC, cSEP )
-import CmdLineOpts     ( opt_OmitInterfacePragmas, opt_EnsureSplittableC, all_toplev_ids_visible )
-import BasicTypes      ( SYN_IE(Module), IfaceFlavour(..), moduleString, pprModule )
-
-import Outputable      ( Outputable(..), PprStyle(..), codeStyle, ifaceStyle, userStyle )
-import PrelMods                ( gHC__ )
-import Pretty
-import Lex             ( isLexSym, isLexConId )
-import SrcLoc          ( noSrcLoc, SrcLoc )
-import Usage            ( SYN_IE(UVar), SYN_IE(Usage) )
-import Unique          ( pprUnique, showUnique, Unique, Uniquable(..) )
-import UniqSet         ( UniqSet(..), emptyUniqSet, unitUniqSet, unionUniqSets, uniqSetToList, isEmptyUniqSet,
-                         unionManyUniqSets, minusUniqSet, mkUniqSet, elementOfUniqSet, addListToUniqSet, addOneToUniqSet )
-import UniqFM          ( UniqFM )
-import Util            ( Ord3(..), cmpPString, panic, assertPanic {-, pprTrace ToDo:rm-} )
+
+import CStrings                ( identToC )
+import PrelMods                ( pREL_BASE, pREL_TUP, pREL_GHC )
+import CmdLineOpts     ( opt_PprStyle_NoPrags, opt_OmitInterfacePragmas, opt_EnsureSplittableC )
+import BasicTypes      ( Module, IfaceFlavour(..), moduleString, pprModule )
+
+import SrcLoc          ( noSrcLoc, mkBuiltinSrcLoc, SrcLoc )
+import Unique          ( pprUnique, Unique, Uniquable(..) )
+import Outputable
+import Char            ( isUpper, isLower, ord )
+import Util            ( nOfThem )
+import GlaExts
+\end{code}
+
+
+%************************************************************************
+%*                                                                     *
+\subsection{Lexical categories}
+%*                                                                     *
+%************************************************************************
+
+These functions test strings to see if they fit the lexical categories
+defined in the Haskell report.
+
+\begin{code}
+isLexCon, isLexVar, isLexId, isLexSym, isLexConId, isLexConSym,
+ isLexVarId, isLexVarSym  :: FAST_STRING -> Bool
+
+isLexCon cs = isLexConId  cs || isLexConSym cs
+isLexVar cs = isLexVarId  cs || isLexVarSym cs
+
+isLexId  cs = isLexConId  cs || isLexVarId  cs
+isLexSym cs = isLexConSym cs || isLexVarSym cs
+
+-------------
+
+isLexConId cs
+  | _NULL_ cs       = False
+  | cs == SLIT("[]") = True
+  | c  == '('       = True     -- (), (,), (,,), ...
+  | otherwise       = isUpper c || isUpperISO c
+  where                                        
+    c = _HEAD_ cs
+
+isLexVarId cs
+  | _NULL_ cs   = False
+  | otherwise    = isLower c || isLowerISO c
+  where
+    c = _HEAD_ cs
+
+isLexConSym cs
+  | _NULL_ cs  = False
+  | otherwise  = c  == ':'
+              || cs == SLIT("->")
+  where
+    c = _HEAD_ cs
+
+isLexVarSym cs
+  | _NULL_ cs = False
+  | otherwise = isSymbolASCII c
+            || isSymbolISO c
+  where
+    c = _HEAD_ cs
+
+-------------
+isSymbolASCII c = c `elem` "!#$%&*+./<=>?@\\^|~-"
+isSymbolISO   c = ord c `elem` (0xd7 : 0xf7 : [0xa1 .. 0xbf])
+isUpperISO    (C# c#) = c# `geChar#` '\xc0'# && c# `leChar#` '\xde'# && c# `neChar#` '\xd7'#
+--0xc0 <= oc && oc <= 0xde && oc /= 0xd7 where oc = ord c
+isLowerISO    (C# c#) = c# `geChar#` '\xdf'# && c# `leChar#` '\xff'# && c# `neChar#` '\xf7'#
+--0xdf <= oc && oc <= 0xff && oc /= 0xf7 where oc = ord c
+\end{code}
+
+\begin{code}
+mkTupNameStr 0 = (pREL_BASE, SLIT("()"))
+mkTupNameStr 1 = panic "Name.mkTupNameStr: 1 ???"
+mkTupNameStr 2 = (pREL_TUP, _PK_ "(,)")   -- not strictly necessary
+mkTupNameStr 3 = (pREL_TUP, _PK_ "(,,)")  -- ditto
+mkTupNameStr 4 = (pREL_TUP, _PK_ "(,,,)") -- ditto
+mkTupNameStr n = (pREL_TUP, _PK_ ("(" ++ nOfThem (n-1) ',' ++ ")"))
+
+mkUbxTupNameStr 0 = panic "Name.mkUbxTupNameStr: 0 ???"
+mkUbxTupNameStr 1 = (pREL_GHC, _PK_ "(# #)") -- 1 and 0 both make sense!!!
+mkUbxTupNameStr 2 = (pREL_GHC, _PK_ "(#,#)")
+mkUbxTupNameStr 3 = (pREL_GHC, _PK_ "(#,,#)")
+mkUbxTupNameStr 4 = (pREL_GHC, _PK_ "(#,,,#)")
+mkUbxTupNameStr n = (pREL_GHC, _PK_ ("(#" ++ nOfThem (n-1) ',' ++ "#)"))
 \end{code}
 
 
@@ -90,16 +160,25 @@ data OccName  = VarOcc  FAST_STRING        -- Variables and data constructors
              | TvOcc   FAST_STRING     -- Type variables
              | TCOcc   FAST_STRING     -- Type constructors and classes
 
-pprOccName :: PprStyle -> OccName -> Doc
-pprOccName sty      n = if codeStyle sty 
-                       then identToC (occNameString n)
-                       else ptext (occNameString n)
+pprOccName :: OccName -> SDoc
+pprOccName n = getPprStyle $ \ sty ->
+              if codeStyle sty 
+              then identToC (occNameString n)
+              else ptext (occNameString n)
+
+varOcc :: FAST_STRING -> OccName
+varOcc = VarOcc
 
 occNameString :: OccName -> FAST_STRING
 occNameString (VarOcc s)  = s
 occNameString (TvOcc s)   = s
 occNameString (TCOcc s)   = s
 
+mapOccName :: (FAST_STRING -> FAST_STRING) -> OccName -> OccName
+mapOccName f (VarOcc s) = VarOcc (f s)
+mapOccName f (TvOcc s)  = TvOcc  (f s)
+mapOccName f (TCOcc s)  = TCOcc  (f s)
+
 prefixOccName :: FAST_STRING -> OccName -> OccName
 prefixOccName prefix (VarOcc s) = VarOcc (prefix _APPEND_ s)
 prefixOccName prefix (TvOcc s)  = TvOcc (prefix _APPEND_ s)
@@ -125,27 +204,25 @@ isTCOcc (TCOcc s) = True
 isTCOcc other     = False
 
 instance Eq OccName 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 OccName 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  }
+    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 = cmpOcc a b
 
-instance Ord3 OccName where
-    cmp = cmpOcc
+(VarOcc s1) `cmpOcc` (VarOcc s2) = s1 `compare` s2
+(VarOcc s1) `cmpOcc` other2      = LT
 
-(VarOcc s1) `cmpOcc` (VarOcc s2) = s1 `_CMP_STRING_` s2
-(VarOcc s1) `cmpOcc` other2      = LT_
+(TvOcc s1)  `cmpOcc` (VarOcc s2) = GT
+(TvOcc s1)  `cmpOcc` (TvOcc s2)  = s1 `compare` s2
+(TvOcc s1)  `cmpOcc` other      = LT
 
-(TvOcc s1)  `cmpOcc` (VarOcc s2) = GT_
-(TvOcc s1)  `cmpOcc` (TvOcc s2)  = s1 `_CMP_STRING_` s2
-(TvOcc s1)  `cmpOcc` other      = LT_
-
-(TCOcc s1) `cmpOcc` (TCOcc s2) = s1 `_CMP_STRING_` s2
-(TCOcc s1) `cmpOcc` other      = GT_
+(TCOcc s1) `cmpOcc` (TCOcc s2) = s1 `compare` s2
+(TCOcc s1) `cmpOcc` other      = GT
 
 instance Outputable OccName where
   ppr = pprOccName
@@ -161,8 +238,7 @@ instance Outputable OccName where
 \begin{code}
 data Name
   = Local    Unique
-             OccName
-             SrcLoc
+            (Maybe OccName)    -- For ones that started life with a user name
 
   | Global   Unique
             Module             -- The defining module
@@ -177,13 +253,23 @@ must be made @Global@ first.
 
 \begin{code}
 data Provenance
-  = LocalDef ExportFlag SrcLoc         -- Locally defined
-  | Imported Module SrcLoc IfaceFlavour        -- Directly imported from M; 
-                                       --              gives name of module in import statement
-                                       --              and locn of import statement
-  | Implicit IfaceFlavour              -- Implicitly imported
+  = NoProvenance
+
+  | LocalDef                   -- Defined locally
+       SrcLoc                  -- Defn site
+       ExportFlag              -- Whether it's exported
+
+  | NonLocalDef                -- Defined non-locally
+       SrcLoc                  -- Defined non-locally; src-loc gives defn site
+       IfaceFlavour            -- Whether the defn site is an .hi-boot file
+       PrintUnqualified
+
   | WiredInTyCon TyCon                 -- There's a wired-in version
   | WiredInId    Id                    -- ...ditto...
+
+type PrintUnqualified = Bool   -- True <=> the unqualified name of this thing is
+                               -- in scope in this module, so print it 
+                               -- unqualified in error messages
 \end{code}
 
 Something is "Exported" if it may be mentioned by another module without
@@ -192,7 +278,10 @@ never be dropped as dead code, even if they aren't used in this module.
 Furthermore, being Exported means that we can't see all call sites of the thing.
 
 Exported things include:
-       - explicitly exported Ids, including data constructors, class method selectors
+
+       - explicitly exported Ids, including data constructors, 
+         class method selectors
+
        - dfuns from instance decls
 
 Being Exported is *not* the same as finally appearing in the .o file's 
@@ -205,14 +294,14 @@ data ExportFlag = Exported  | NotExported
 \end{code}
 
 \begin{code}
-mkLocalName    :: Unique -> OccName -> SrcLoc -> Name
-mkLocalName = Local
+mkLocalName    :: Unique -> OccName -> Name
+mkLocalName uniq occ = Local uniq (Just occ)
 
 mkGlobalName :: Unique -> Module -> OccName -> Provenance -> Name
 mkGlobalName = Global
 
-mkSysLocalName :: Unique -> FAST_STRING -> SrcLoc -> Name
-mkSysLocalName uniq str loc = Local uniq (VarOcc str) loc
+mkSysLocalName :: Unique -> Name
+mkSysLocalName uniq = Local uniq Nothing
 
 mkWiredInIdName :: Unique -> Module -> FAST_STRING -> Id -> Name
 mkWiredInIdName uniq mod occ id 
@@ -223,43 +312,36 @@ mkWiredInTyConName uniq mod occ tycon
   = Global uniq mod (TCOcc occ) (WiredInTyCon tycon)
 
 
-mkCompoundName :: (FAST_STRING -> FAST_STRING) -- Occurrence-name modifier
-              -> Unique                        -- New unique
-              -> Name                          -- Base name (must be a Global)
+mkCompoundName :: (OccName -> OccName)
+              -> Unique                -- New unique
+              -> Name                  -- Base name
               -> Name          -- Result is always a value name
 
-mkCompoundName str_fn uniq (Global _ mod occ prov)
-  = Global uniq mod new_occ prov
-  where    
-    new_occ = VarOcc (str_fn (occNameString occ))              -- Always a VarOcc
+mkCompoundName f uniq (Global _ mod occ prov)
+  = Global uniq mod (f occ) prov
 
-mkCompoundName str_fn uniq (Local _ occ loc)
-  = Local uniq (VarOcc (str_fn (occNameString occ))) loc
-
-       -- Rather a wierd one that's used for names generated for instance decls
-mkInstDeclName :: Unique -> Module -> OccName -> SrcLoc -> Bool -> Name
-mkInstDeclName uniq mod occ loc from_here
-  = Global uniq mod occ prov
-  where
-    prov | from_here = LocalDef Exported loc
-         | otherwise = Implicit HiFile         -- Odd
+mkCompoundName f uniq (Local _ (Just occ))
+  = Local uniq (Just (f occ))
 
+mkCompoundName f uniq (Local _ Nothing)
+  = Local uniq Nothing
 
 setNameProvenance :: Name -> Provenance -> Name        
-       -- setNameProvenance used to only change the provenance of Implicit-provenance things,
-       -- but that gives bad error messages for names defined twice in the same
-       -- module, so I changed it to set the proveance of *any* global (SLPJ Jun 97)
+       -- setNameProvenance used to only change the provenance of 
+       -- Implicit-provenance things, but that gives bad error messages 
+       -- for names defined twice in the same module, so I changed it to 
+       -- set the provenance of *any* global (SLPJ Jun 97)
 setNameProvenance (Global uniq mod occ _) prov = Global uniq mod occ prov
 setNameProvenance other_name             prov = other_name
 
 getNameProvenance :: Name -> Provenance
 getNameProvenance (Global uniq mod occ prov) = prov
-getNameProvenance (Local uniq occ locn)      = LocalDef NotExported locn
+getNameProvenance (Local uniq occ)           = LocalDef noSrcLoc NotExported
 
 -- 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.
-changeUnique (Local      _ n l)  u = Local u n l
+changeUnique (Local      _ n )          u = Local u n
 changeUnique (Global   _ mod occ  prov) u = Global u mod occ prov
 \end{code}
 
@@ -304,28 +386,37 @@ are exported.  But also:
 \begin{code}
 setNameVisibility :: Maybe Module -> Unique -> Name -> Name
 
-setNameVisibility maybe_mod occ_uniq name@(Global uniq mod occ (LocalDef NotExported loc))
+setNameVisibility maybe_mod uniq name@(Global _ mod occ (LocalDef loc NotExported))
   | not all_toplev_ids_visible || not_top_level maybe_mod
-  = Local uniq (uniqToOccName occ_uniq) loc    -- Localise Global name
+  = Local uniq Nothing                         -- Localise Global name
 
-setNameVisibility maybe_mod occ_uniq name@(Global _ _ _ _)
+setNameVisibility maybe_mod uniq name@(Global _ _ _ _)
   = name                                       -- Otherwise don't fiddle with Global
 
-setNameVisibility (Just mod) occ_uniq (Local uniq occ loc)
+setNameVisibility (Just mod) uniq (Local _ _)
   | all_toplev_ids_visible
   = Global uniq mod                            -- Globalise Local name
-          (uniqToOccName occ_uniq)
-          (LocalDef NotExported loc)
+          (uniqToOccName uniq)
+          (LocalDef noSrcLoc NotExported)
+
+setNameVisibility maybe_mod uniq (Local _ _)
+  = Local uniq Nothing                         -- New unique for Local; zap its occ
 
-setNameVisibility maybe_mod occ_uniq (Local uniq occ loc)
-  = Local uniq (uniqToOccName occ_uniq) loc    -- New OccName for Local
+-- make the Name globally visible regardless.
+mkNameVisible :: Module -> Unique -> Name -> Name
+mkNameVisible mod occ_uniq nm@(Global _ _ _ _) = nm
+mkNameVisible mod occ_uniq nm@(Local uniq occ)
+ = Global uniq mod (uniqToOccName occ_uniq) (LocalDef noSrcLoc Exported)
 
-uniqToOccName uniq = VarOcc (_PK_ ('$':showUnique uniq))
-       -- The "$" is to make sure that this OccName is distinct from all user-defined ones
+uniqToOccName uniq = VarOcc (_PK_ ('_':show uniq))
+       -- The "_" is to make sure that this OccName is distinct from all user-defined ones
 
 not_top_level (Just m) = False
 not_top_level Nothing  = True
 
+all_toplev_ids_visible = 
+       not opt_OmitInterfacePragmas ||  -- Pragmas can make them visible
+       opt_EnsureSplittableC            -- Splitting requires visiblilty
 \end{code}
 
 %************************************************************************
@@ -339,37 +430,38 @@ nameUnique                :: Name -> Unique
 nameModAndOcc          :: Name -> (Module, OccName)    -- Globals only
 nameOccName            :: Name -> OccName 
 nameModule             :: Name -> Module
-nameString             :: Name -> FAST_STRING          -- A.b form
 nameSrcLoc             :: Name -> SrcLoc
 isLocallyDefinedName   :: Name -> Bool
 isExportedName         :: Name -> Bool
 isWiredInName          :: Name -> Bool
 isLocalName            :: Name -> Bool
+isGlobalName           :: Name -> Bool
+isExternallyVisibleName :: Name -> Bool
 
 
 
-nameUnique (Local  u _ _)   = u
+nameUnique (Local  u _)     = u
 nameUnique (Global u _ _ _) = u
 
-nameOccName (Local _ occ _)    = occ
-nameOccName (Global _ _ occ _) = occ
+nameOccName (Local _ (Just occ)) = occ
+nameOccName (Local uniq Nothing) = pprPanic "nameOccName" (ppr uniq)
+nameOccName (Global _ _ occ _)   = occ
 
 nameModule (Global _ mod occ _) = mod
 
 nameModAndOcc (Global _ mod occ _) = (mod,occ)
 
-nameString (Local _ occ _)      = occNameString occ
-nameString (Global _ mod occ _) = mod _APPEND_ SLIT(".") _APPEND_ occNameString occ
-
-isExportedName (Global _ _ _ (LocalDef Exported _)) = True
+isExportedName (Global _ _ _ (LocalDef _ Exported)) = True
 isExportedName other                               = False
 
-nameSrcLoc (Local _ _ loc)     = loc
-nameSrcLoc (Global _ _ _ (LocalDef _ loc))   = loc
-nameSrcLoc (Global _ _ _ (Imported _ loc _)) = loc
-nameSrcLoc other                            = noSrcLoc
+nameSrcLoc (Local _ _)                         = noSrcLoc
+nameSrcLoc (Global _ _ _ (LocalDef loc _))      = loc
+nameSrcLoc (Global _ _ _ (NonLocalDef loc _ _)) = loc
+nameSrcLoc (Global _ _ _ (WiredInTyCon _))      = mkBuiltinSrcLoc
+nameSrcLoc (Global _ _ _ (WiredInId _))         = mkBuiltinSrcLoc
+nameSrcLoc other                               = noSrcLoc
   
-isLocallyDefinedName (Local  _ _ _)                 = True
+isLocallyDefinedName (Local  _ _)                 = True
 isLocallyDefinedName (Global _ _ _ (LocalDef _ _)) = True
 isLocallyDefinedName other                        = False
 
@@ -379,7 +471,7 @@ isLocallyDefinedName other                     = False
 -- them out, often in combination with isLocallyDefined.
 isWiredInName (Global _ _ _ (WiredInTyCon _)) = True
 isWiredInName (Global _ _ _ (WiredInId    _)) = True
-isWiredInName _                                          = False
+isWiredInName _                                      = False
 
 maybeWiredInIdName :: Name -> Maybe Id
 maybeWiredInIdName (Global _ _ _ (WiredInId id)) = Just id
@@ -390,8 +482,19 @@ maybeWiredInTyConName (Global _ _ _ (WiredInTyCon tc)) = Just tc
 maybeWiredInTyConName other                           = Nothing
 
 
-isLocalName (Local _ _ _) = True
-isLocalName _            = False
+isLocalName (Local _ _) = True
+isLocalName _          = False
+
+isSysLocalName (Local _ Nothing) = True
+isSysLocalName other            = False
+
+isGlobalName (Global _ _ _ _) = True
+isGlobalName other           = False
+
+-- 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 (that's isExported).
+isExternallyVisibleName name = isGlobalName name
 \end{code}
 
 
@@ -404,137 +507,211 @@ isLocalName _             = False
 \begin{code}
 cmpName n1 n2 = c n1 n2
   where
-    c (Local  u1 _ _)   (Local  u2 _ _)   = cmp u1 u2
-    c (Local   _ _ _)    _               = LT_
-    c (Global u1 _ _ _) (Global u2 _ _ _) = cmp u1 u2
-    c (Global  _ _ _ _)   _              = GT_
+    c (Local  u1 _)   (Local  u2 _)       = compare u1 u2
+    c (Local   _ _)      _               = LT
+    c (Global u1 _ _ _) (Global u2 _ _ _) = compare u1 u2
+    c (Global  _ _ _ _)   _              = GT
 \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}
 
 
-
 %************************************************************************
 %*                                                                     *
-\subsection{Pretty printing}
+\subsection[Special-Names]{Special Kinds of names}
 %*                                                                     *
 %************************************************************************
 
-\begin{code}
-instance Outputable Name where
-    ppr PprQuote name@(Local _ _ _)  = quotes (ppr (PprForUser 1) name)
-
-       -- When printing interfaces, all Locals have been given nice print-names
-    ppr (PprForUser _) (Local _ n _) = ptext (occNameString n)
-    ppr PprInterface   (Local _ n _) = ptext (occNameString n)
+Here's our convention for splitting up the object file name space:
 
-    ppr sty (Local u n _) | codeStyle sty = pprUnique u
+       _d...           dictionary identifiers
+       _g...           externally visible (non-user visible) names
 
-    ppr sty (Local u n _) = hcat [ptext (occNameString n), ptext SLIT("_"), pprUnique u]
+       _m...           default methods
+       _n...           default methods (encoded symbols, eg. <= becomes _nle)
 
-    ppr PprQuote name@(Global _ _ _ _) = quotes (ppr (PprForUser 1) name)
+       _p...           superclass selectors
 
-    ppr sty name@(Global u m n _)
-       | codeStyle sty
-       = identToC (m _APPEND_ SLIT(".") _APPEND_ occNameString n)
+       _w...           workers
+       _v...           workers (encoded symbols)
 
-    ppr sty name@(Global u m n prov)
-       = hcat [pp_mod_dot, ptext (occNameString n), pp_debug sty name]
-       where
-         pp_mod = pprModule (PprForUser 1) m 
+       _x...           local variables
 
-         pp_mod_dot | userStyle sty            -- Omit qualifier in user style
-                    = empty
-                    | otherwise
-                    = case prov of             -- Omit home module qualifier
-                       LocalDef _ _     -> empty
-                       Imported _ _ hif -> pp_mod <> pp_dot hif
-                       Implicit hif     -> pp_mod <> pp_dot hif
-                       other            -> pp_mod <> text "."
+       _u...           user-defined names that previously began with '_'
 
-         pp_dot HiFile     = text "."          -- Vanilla case
-         pp_dot HiBootFile = text "!"          -- M!t indicates a name imported from 
-                                               -- a .hi-boot interface
+       _[A-Z]...       compiler-generated tycons/datacons (namely dictionary
+                       constructors)
 
+       __....          keywords (__export, __letrec etc.)
 
-pp_debug PprDebug (Global uniq m n prov) = hcat [text "{-", pprUnique uniq, char ',', 
-                                                       pp_prov prov, text "-}"]
-                                       where
-                                               pp_prov (LocalDef Exported _)    = char 'x'
-                                               pp_prov (LocalDef NotExported _) = char 'l'
-                                               pp_prov (Imported _ _ _) = char 'i'
-                                               pp_prov (Implicit _)     = char 'p'
-                                               pp_prov (WiredInTyCon _) = char 'W'
-                                               pp_prov (WiredInId _)    = char 'w'
-pp_debug other    name                         = empty
+This knowledge is encoded in the following functions.
 
--- pprNameProvenance is used in error messages to say where a name came from
-pprNameProvenance :: PprStyle -> Name -> Doc
-pprNameProvenance sty (Local _ _ loc)     = pprProvenance sty (LocalDef NotExported loc)
-pprNameProvenance sty (Global _ _ _ prov) = pprProvenance sty prov
-
-pprProvenance :: PprStyle -> Provenance -> Doc
-pprProvenance sty (Imported mod loc _)
-  = sep [ptext SLIT("Imported from"), pprModule sty mod, ptext SLIT("at"), ppr sty loc]
-pprProvenance sty (LocalDef _ loc)  = sep [ptext SLIT("Defined at"), ppr sty loc]
-pprProvenance sty (Implicit _)      = panic "pprNameProvenance: Implicit"
-pprProvenance sty (WiredInTyCon tc) = ptext SLIT("Wired-in tycon")
-pprProvenance sty (WiredInId id)    = ptext SLIT("Wired-in id")
+\begin{code}
+dictNamePrefix :: FAST_STRING
+dictNamePrefix = SLIT("_d")
+
+mkSuperDictSelName :: Int -> OccName -> OccName
+mkSuperDictSelName index = prefixOccName (_PK_ ("_p" ++ show index ++ "_"))
+
+mkWorkerName :: OccName -> OccName
+mkWorkerName nm
+  | isLexSym nm_str = 
+       prefixOccName SLIT("_v") (mapOccName trName nm)
+  | otherwise               = 
+       prefixOccName SLIT("_w") nm
+  where nm_str = occNameString nm
+
+mkDefaultMethodName :: OccName -> OccName
+mkDefaultMethodName nm
+  | isLexSym nm_str = 
+       prefixOccName SLIT("_n") (mapOccName trName nm)
+  | otherwise               = 
+       prefixOccName SLIT("_m") nm
+  where nm_str = occNameString nm
+
+-- not used yet:
+--mkRecordSelectorName     :: Name -> Name
+--mkMethodSelectorName     :: Name -> Name
+
+mkClassTyConStr, mkClassDataConStr :: FAST_STRING -> FAST_STRING
+
+mkClassTyConStr   s = SLIT("_") _APPEND_ s
+mkClassDataConStr s = SLIT("_") _APPEND_ s
+
+-- translate a string such that it can occur as *part* of an identifer.  This
+-- is used when we prefix identifiers to create new names, for example the
+-- name of a default method.
+
+trName :: FAST_STRING -> FAST_STRING
+trName nm = _PK_ (foldr tran "" (_UNPK_ nm))
+ where 
+    tran c cs = case trChar c of
+                  '\0' -> '_' : show (ord c) ++ cs
+                  c'   -> c' : cs
+    trChar '&'  = 'a'
+    trChar '|'  = 'b'
+    trChar ':'  = 'c'
+    trChar '/'  = 'd'
+    trChar '='  = 'e'
+    trChar '>'  = 'g'
+    trChar '#'  = 'h'
+    trChar '@'  = 'i'
+    trChar '<'  = 'l'
+    trChar '-'  = 'm'
+    trChar '!'  = 'n'
+    trChar '+'  = 'p'
+    trChar '\'' = 'q'
+    trChar '$'  = 'r'
+    trChar '?'  = 's'
+    trChar '*'  = 't'
+    trChar '_'  = 'u'
+    trChar '.'  = 'v'
+    trChar '\\' = 'w'
+    trChar '%'  = 'x'
+    trChar '~'  = 'y'
+    trChar '^'  = 'z'
+    trChar _    = '\0'
 \end{code}
 
-
 %************************************************************************
 %*                                                                     *
-\subsection[Sets of names}
+\subsection{Pretty printing}
 %*                                                                     *
 %************************************************************************
 
 \begin{code}
-type NameSet = UniqSet Name
-emptyNameSet     :: NameSet
-unitNameSet      :: Name -> NameSet
-addListToNameSet  :: NameSet -> [Name] -> NameSet
-addOneToNameSet   :: NameSet -> Name -> NameSet
-mkNameSet         :: [Name] -> NameSet
-unionNameSets    :: NameSet -> NameSet -> NameSet
-unionManyNameSets :: [NameSet] -> NameSet
-minusNameSet     :: NameSet -> NameSet -> NameSet
-elemNameSet      :: Name -> NameSet -> Bool
-nameSetToList    :: NameSet -> [Name]
-isEmptyNameSet   :: NameSet -> Bool
-
-isEmptyNameSet    = isEmptyUniqSet
-emptyNameSet     = emptyUniqSet
-unitNameSet      = unitUniqSet
-mkNameSet         = mkUniqSet
-addListToNameSet  = addListToUniqSet
-addOneToNameSet          = addOneToUniqSet
-unionNameSets     = unionUniqSets
-unionManyNameSets = unionManyUniqSets
-minusNameSet     = minusUniqSet
-elemNameSet       = elementOfUniqSet
-nameSetToList     = uniqSetToList
-\end{code}
+instance Outputable Name where
+       -- When printing interfaces, all Locals have been given nice print-names
+    ppr name = pprName name
+
+pprName name
+  = getPprStyle $ \ sty ->
+    let
+       -- when printing local names for interface files, prepend the '_'
+       -- to avoid clashes with user-defined names.  In fact, these names
+       -- will always begin with 'g' for top-level ids and 'x' otherwise,
+       -- because these are the unique supplies going into the tidy phase.
+       ppr (Local u n) | codeStyle sty   = pprUnique u
+                      | ifaceStyle sty  = char '_' <> pprUnique u
+
+       ppr (Local u Nothing)   = pprUnique u
+       ppr (Local u (Just occ))        | userStyle sty = ptext (occNameString occ)
+                               | otherwise     = ptext (occNameString occ) <> char '_' <> pprUnique u
+   
+       ppr name@(Global u m n prov)
+        | codeStyle sty
+        = identToC (m _APPEND_ SLIT(".") _APPEND_ occNameString n)
+   
+        | otherwise  
+        = hcat [pp_mod_dot, ptext (occNameString n), pp_debug sty name]
+        where
+          pp_mod_dot 
+            = case prov of   -- Omit home module qualifier if in scope 
+                  LocalDef _ _          -> pp_qual dot (user_sty || iface_sty)
+                  NonLocalDef _ hif omit -> pp_qual (pp_hif hif) (omit && user_sty)
+                                -- Hack: omit qualifers on wired in things
+                                -- in user style only
+                  WiredInTyCon _       -> pp_qual dot user_sty
+                  WiredInId _          -> pp_qual dot user_sty
+                  NoProvenance         -> pp_qual dot False
+   
+          pp_qual sep omit_qual
+           | omit_qual  = empty
+           | otherwise  = pprModule m <> sep
+
+          dot = text "."
+          pp_hif HiFile     = dot       -- Vanilla case
+          pp_hif HiBootFile = text "!"  -- M!t indicates a name imported from a .hi-boot interface
+
+          user_sty  = userStyle sty
+          iface_sty = ifaceStyle sty
+    in
+    ppr name
+   
+   
+pp_debug sty (Global uniq m n prov) 
+  | debugStyle sty = hcat [text "{-", pprUnique uniq, prov_p, text "-}"]
+  | otherwise     = empty
+                  where
+                    prov_p | opt_PprStyle_NoPrags = empty
+                           | otherwise            = comma <> pp_prov prov
+
+pp_prov (LocalDef _ Exported)    = char 'x'
+pp_prov (LocalDef _ NotExported) = char 'l'
+pp_prov (NonLocalDef _ _ _)             = char 'n'
+pp_prov (WiredInTyCon _)        = char 'W'
+pp_prov (WiredInId _)           = char 'w'
+pp_prov NoProvenance            = char '?'
 
+-- pprNameProvenance is used in error messages to say where a name came from
+pprNameProvenance :: Name -> SDoc
+pprNameProvenance (Local _ _)         = pprProvenance (LocalDef noSrcLoc NotExported)
+pprNameProvenance (Global _ _ _ prov) = pprProvenance prov
+
+pprProvenance :: Provenance -> SDoc
+pprProvenance (LocalDef loc _)      = ptext SLIT("Locally defined at")     <+> ppr loc
+pprProvenance (NonLocalDef loc _ _) = ptext SLIT("Non-locally defined at") <+> ppr loc
+pprProvenance (WiredInTyCon tc)     = ptext SLIT("Wired-in tycon")
+pprProvenance (WiredInId id)        = ptext SLIT("Wired-in id")
+pprProvenance NoProvenance         = ptext SLIT("No provenance")
+\end{code}
 
 
 %************************************************************************
@@ -553,14 +730,12 @@ class NamedThing a where
 
 \begin{code}
 modAndOcc          :: NamedThing a => a -> (Module, OccName)
-getModule          :: NamedThing a => a -> Module
 getSrcLoc          :: NamedThing a => a -> SrcLoc
 isLocallyDefined    :: NamedThing a => a -> Bool
 isExported         :: NamedThing a => a -> Bool
 getOccString       :: NamedThing a => a -> String
 
 modAndOcc          = nameModAndOcc        . getName
-getModule          = nameModule           . getName
 isExported         = isExportedName       . getName
 getSrcLoc          = nameSrcLoc           . getName
 isLocallyDefined    = isLocallyDefinedName . getName