[project @ 1998-12-02 13:17:09 by simonm]
[ghc-hetmet.git] / ghc / compiler / basicTypes / Name.lhs
index 1750dc7..5fc667c 100644 (file)
@@ -1,52 +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,
-       quoteInText, parenInCode,
 
        -- 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
-       DefnInfo(..),
        Provenance(..), pprProvenance,
-       ExportFlag(..),
+       ExportFlag(..), 
+       PrintUnqualified,
 
        -- Class NamedThing and overloaded friends
        NamedThing(..),
@@ -54,30 +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 )
-import BasicTypes      ( SYN_IE(Module), moduleString, pprModule )
-
-import Outputable      ( Outputable(..), PprStyle(..), codeStyle, ifaceStyle )
-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            --( 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}
 
 
@@ -92,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)
@@ -126,42 +203,32 @@ isTvOcc other     = False
 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  }
-
-instance Ord3 OccName where
-    cmp = cmpOcc
+    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
 
-(VarOcc s1) `cmpOcc` (VarOcc s2) = s1 `_CMP_STRING_` s2
-(VarOcc s1) `cmpOcc` other2      = LT_
+(VarOcc s1) `cmpOcc` (VarOcc s2) = s1 `compare` s2
+(VarOcc s1) `cmpOcc` other2      = LT
 
-(TvOcc s1)  `cmpOcc` (VarOcc s2) = GT_
-(TvOcc s1)  `cmpOcc` (TvOcc s2)  = s1 `_CMP_STRING_` s2
-(TvOcc s1)  `cmpOcc` other      = LT_
+(TvOcc s1)  `cmpOcc` (VarOcc s2) = GT
+(TvOcc s1)  `cmpOcc` (TvOcc s2)  = s1 `compare` 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
 \end{code}
 
 
-\begin{code}
-parenInCode, quoteInText :: OccName -> Bool
-parenInCode occ = isLexSym (occNameString occ)
-
-quoteInText occ = not (isLexSym (occNameString occ))
-\end{code}
-
 %************************************************************************
 %*                                                                     *
 \subsection[Name-datatype]{The @Name@ datatype, and name construction}
@@ -171,14 +238,12 @@ quoteInText occ = not (isLexSym (occNameString occ))
 \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
             OccName            -- Its name in that module
-            DefnInfo           -- How it is defined
-             Provenance                -- How it was brought into scope
+             Provenance                -- How it was defined
 \end{code}
 
 Things with a @Global@ name are given C static labels, so they finally
@@ -187,14 +252,24 @@ in the form M.n.  If originally-local things have this property they
 must be made @Global@ first.
 
 \begin{code}
-data DefnInfo =        VanillaDefn     
-             | WiredInTyCon TyCon      -- There's a wired-in version
-             | WiredInId    Id         -- ...ditto...
-
 data Provenance
-  = LocalDef ExportFlag SrcLoc -- Locally defined
-  | Imported Module SrcLoc     -- Directly imported from M; gives locn of import statement
-  | Implicit                   -- 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
@@ -203,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 
@@ -216,85 +294,129 @@ 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 -> DefnInfo -> Provenance -> Name
+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 
-  = Global uniq mod (VarOcc occ) (WiredInId id) Implicit
+  = Global uniq mod (VarOcc occ) (WiredInId id)
 
 mkWiredInTyConName :: Unique -> Module -> FAST_STRING -> TyCon -> Name
 mkWiredInTyConName uniq mod occ tycon
-  = Global uniq mod (TCOcc occ) (WiredInTyCon tycon) Implicit
+  = 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 defn prov)
-  = Global uniq mod new_occ defn prov
-  where    
-    new_occ = VarOcc (str_fn (occNameString occ))              -- Always a VarOcc
-
-mkCompoundName str_fn uniq (Local _ occ loc)
-  = Local uniq (VarOcc (str_fn (occNameString occ))) loc
+mkCompoundName f uniq (Global _ mod occ prov)
+  = Global uniq mod (f occ) prov
 
-       -- 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 VanillaDefn prov
-  where
-    prov | from_here = LocalDef Exported loc
-         | otherwise = Implicit
+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 (Global uniq mod occ def _) prov = Global uniq mod occ def prov
-setNameProvenance other_name                 prov = other_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 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 def prov) = prov
-getNameProvenance (Local uniq occ locn)         = LocalDef NotExported locn
+getNameProvenance (Global uniq mod occ prov) = prov
+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 (Global   _ mod occ def prov) u = Global u mod occ def prov
+changeUnique (Local      _ n )          u = Local u n
+changeUnique (Global   _ mod occ  prov) u = Global u mod occ prov
+\end{code}
+
+setNameVisibility is applied to names in the final program
+
+The Maybe Module argument is (Just mod) for top-level values,
+and Nothing for all others (local values and type variables)
+
+For top-level things, it globalises Local names 
+                               (if all top-level things should be visible)
+                        and localises non-exported Global names
+                                (if only exported things should be visible)
 
-setNameVisibility :: Module -> Name -> Name
--- setNameVisibility is applied to top-level names in the final program
--- The "visibility" here concerns whether the .o file's symbol table
--- mentions the thing; if so, it needs a module name in its symbol,
--- otherwise we just use its unique.  The Global things are "visible"
--- and the local ones are not
+For nested things it localises Global names.
 
-setNameVisibility _ (Global uniq mod occ def (LocalDef NotExported loc))
-  | not all_toplev_ids_visible
-  = Local uniq occ loc
+In all cases except an exported global, it gives it a new occurrence name.
 
-setNameVisibility mod (Local uniq occ loc)
+The "visibility" here concerns whether the .o file's symbol table
+mentions the thing; if so, it needs a module name in its symbol.
+The Global things are "visible" and the Local ones are not
+
+Why should things be "visible"?  Certainly they must be if they
+are exported.  But also:
+
+(a) In certain (prelude only) modules we split up the .hc file into
+    lots of separate little files, which are separately compiled by the C
+    compiler.  That gives lots of little .o files.  The idea is that if
+    you happen to mention one of them you don't necessarily pull them all
+    in.  (Pulling in a piece you don't need can be v bad, because it may
+    mention other pieces you don't need either, and so on.)
+    
+    Sadly, splitting up .hc files means that local names (like s234) are
+    now globally visible, which can lead to clashes between two .hc
+    files. So unlocaliseWhatnot goes through making all the local things
+    into global things, essentially by giving them full names so when they
+    are printed they'll have their module name too.  Pretty revolting
+    really.
+
+(b) When optimisation is on we want to make all the internal
+    top-level defns externally visible
+
+\begin{code}
+setNameVisibility :: Maybe Module -> Unique -> Name -> Name
+
+setNameVisibility maybe_mod uniq name@(Global _ mod occ (LocalDef loc NotExported))
+  | not all_toplev_ids_visible || not_top_level maybe_mod
+  = Local uniq Nothing                         -- Localise Global name
+
+setNameVisibility maybe_mod uniq name@(Global _ _ _ _)
+  = name                                       -- Otherwise don't fiddle with Global
+
+setNameVisibility (Just mod) uniq (Local _ _)
   | all_toplev_ids_visible
-  = Global uniq mod 
-          (VarOcc (showUnique uniq))   -- It's local name must be unique!
-          VanillaDefn (LocalDef NotExported loc)
+  = Global uniq mod                            -- Globalise Local name
+          (uniqToOccName uniq)
+          (LocalDef noSrcLoc NotExported)
+
+setNameVisibility maybe_mod uniq (Local _ _)
+  = Local uniq Nothing                         -- New unique for Local; zap its occ
+
+-- 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)
 
-setNameVisibility mod name = name
+uniqToOccName uniq = VarOcc (_PK_ ('_':show uniq))
+       -- The "_" is to make sure that this OccName is distinct from all user-defined ones
 
-all_toplev_ids_visible = not opt_OmitInterfacePragmas ||  -- Pragmas can make them visible
-                        opt_EnsureSplittableC            -- Splitting requires visiblilty
+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}
 
 %************************************************************************
@@ -308,59 +430,71 @@ 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 (Global 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
+nameModule (Global _ mod occ _) = mod
 
-nameModAndOcc (Global _ mod occ _ _) = (mod,occ)
+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 other                               = False
 
-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 (Global _ _ _ _ (LocalDef _ _)) = True
-isLocallyDefinedName other                          = False
+isLocallyDefinedName (Local  _ _)                 = True
+isLocallyDefinedName (Global _ _ _ (LocalDef _ _)) = True
+isLocallyDefinedName other                        = False
 
 -- Things the compiler "knows about" are in some sense
 -- "imported".  When we are compiling the module where
 -- the entities are defined, we need to be able to pick
 -- them out, often in combination with isLocallyDefined.
-isWiredInName (Global _ _ _ (WiredInTyCon _) _) = True
-isWiredInName (Global _ _ _ (WiredInId    _) _) = True
-isWiredInName _                                          = False
+isWiredInName (Global _ _ _ (WiredInTyCon _)) = True
+isWiredInName (Global _ _ _ (WiredInId    _)) = True
+isWiredInName _                                      = False
 
 maybeWiredInIdName :: Name -> Maybe Id
-maybeWiredInIdName (Global _ _ _ (WiredInId id) _) = Just id
-maybeWiredInIdName other                          = Nothing
+maybeWiredInIdName (Global _ _ _ (WiredInId id)) = Just id
+maybeWiredInIdName other                        = Nothing
 
 maybeWiredInTyConName :: Name -> Maybe TyCon
-maybeWiredInTyConName (Global _ _ _ (WiredInTyCon tc) _) = Just tc
-maybeWiredInTyConName other                             = Nothing
+maybeWiredInTyConName (Global _ _ _ (WiredInTyCon tc)) = Just tc
+maybeWiredInTyConName other                           = Nothing
+
+
+isLocalName (Local _ _) = True
+isLocalName _          = False
 
+isSysLocalName (Local _ Nothing) = True
+isSysLocalName other            = False
 
-isLocalName (Local _ _ _) = True
-isLocalName _            = 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}
 
 
@@ -373,122 +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)
-    ppr (PprForUser _) (Local _ n _)    = ptext (occNameString n)
+Here's our convention for splitting up the object file name space:
 
-    ppr sty (Local u n _) | codeStyle sty ||
-                           ifaceStyle 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, ptext (occNameString n), pp_debug sty name]
-       where
-         pp_mod = case prov of                         --- Omit home module qualifier
-                       LocalDef _ _ -> empty
-                       other        -> pprModule (PprForUser 1) m <> char '.'
+       _x...           local variables
 
+       _u...           user-defined names that previously began with '_'
 
-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_debug other    name                         = empty
+       _[A-Z]...       compiler-generated tycons/datacons (namely dictionary
+                       constructors)
 
--- 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"
-\end{code}
+       __....          keywords (__export, __letrec etc.)
 
+This knowledge is encoded in the following functions.
+
+\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}
 
 
 %************************************************************************
@@ -507,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