\begin{code}
module Name (
- -- Re-export the Module type
- Module,
- pprModule, moduleString,
-
- -- The basic form of names
- isLexCon, isLexVar, isLexId, isLexSym,
- isLexConId, isLexConSym, isLexVarId, isLexVarSym,
- mkTupNameStr, mkUbxTupNameStr, isLowerISO, isUpperISO,
-
- -- The OccName type
- OccName(..), varOcc,
- pprOccName, occNameString, occNameFlavour,
- isTvOcc, isTCOcc, isVarOcc, prefixOccName,
+ -- Re-export the OccName stuff
+ module OccName,
-- The Name type
Name, -- Abstract
- mkLocalName, mkSysLocalName,
-
- mkCompoundName, mkGlobalName,
-
+ mkLocalName, mkImportedLocalName, mkSysLocalName, mkCCallName,
+ mkTopName, mkIPName,
+ mkDerivedName, mkGlobalName, mkKnownKeyGlobal,
mkWiredInIdName, mkWiredInTyConName,
- maybeWiredInIdName, maybeWiredInTyConName,
- isWiredInName,
+ mkUnboundName, isUnboundName,
- nameUnique, changeUnique, setNameProvenance, getNameProvenance,
- setNameVisibility, mkNameVisible,
- nameOccName, nameModule,
+ maybeWiredInIdName, maybeWiredInTyConName,
+ isWiredInName, hashName,
- isExportedName, nameSrcLoc,
- isLocallyDefinedName,
+ nameUnique, setNameUnique, setNameProvenance, getNameProvenance, setNameImportReason,
+ tidyTopName,
+ nameOccName, nameModule, setNameOcc, nameRdrName, setNameModule, toRdrName,
- isSysLocalName, isLocalName, isGlobalName, isExternallyVisibleName,
+ isUserExportedName, isUserImportedName, isUserImportedExplicitlyName,
+ maybeUserImportedFrom,
+ nameSrcLoc, isLocallyDefinedName, isDllName,
- pprNameProvenance,
+ isSystemName, isLocalName, isGlobalName, isExternallyVisibleName,
+
+ -- Environment
+ NameEnv,
+ emptyNameEnv, unitNameEnv, nameEnvElts,
+ addToNameEnv_C, addToNameEnv, addListToNameEnv,
+ plusNameEnv, plusNameEnv_C, extendNameEnv,
+ lookupNameEnv, delFromNameEnv, elemNameEnv,
- -- Special Names
- dictNamePrefix, mkSuperDictSelName, mkWorkerName,
- mkDefaultMethodName, mkClassTyConStr, mkClassDataConStr,
- -- Misc
- Provenance(..), pprProvenance,
- ExportFlag(..),
- PrintUnqualified,
+ -- Provenance
+ Provenance(..), ImportReason(..), pprProvenance,
+ ExportFlag(..), PrintUnqualified,
+ pprNameProvenance, hasBetterProv,
-- Class NamedThing and overloaded friends
NamedThing(..),
- modAndOcc, isExported,
- getSrcLoc, isLocallyDefined, getOccString
+ getSrcLoc, isLocallyDefined, getOccString, toRdrName
) where
#include "HsVersions.h"
-import {-# SOURCE #-} Var ( Id )
-import {-# SOURCE #-} TyCon ( TyCon )
+import {-# SOURCE #-} Var ( Id, setIdName )
+import {-# SOURCE #-} TyCon ( TyCon, setTyConName )
-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 OccName -- All of it
+import Module ( Module, moduleName, pprModule, mkVanillaModule, isLocalModule )
+import RdrName ( RdrName, mkRdrQual, mkRdrUnqual, rdrNameOcc, rdrNameModule )
+import CmdLineOpts ( opt_Static, opt_PprStyle_NoPrags, opt_OmitInterfacePragmas, opt_EnsureSplittableC )
import SrcLoc ( noSrcLoc, mkBuiltinSrcLoc, SrcLoc )
-import Unique ( pprUnique, Unique, Uniquable(..) )
+import Unique ( pprUnique, Unique, Uniquable(..), hasKey, unboundKey, u2i )
+import UniqFM
import Outputable
-import Char ( isUpper, isLower, ord )
-import Util ( nOfThem )
import GlaExts
\end{code}
%************************************************************************
%* *
-\subsection{Lexical categories}
+\subsection[Name-datatype]{The @Name@ datatype, and name construction}
%* *
%************************************************************************
+
+\begin{code}
+data Name = Name {
+ n_sort :: NameSort, -- What sort of name it is
+ n_uniq :: Unique,
+ n_occ :: OccName, -- Its occurrence name
+ n_prov :: Provenance -- How it was made
+ }
+
+data NameSort
+ = Local
+ | Global Module
+ | WiredInId Module Id
+ | WiredInTyCon Module TyCon
+\end{code}
-These functions test strings to see if they fit the lexical categories
-defined in the Haskell report.
+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.
\begin{code}
-isLexCon, isLexVar, isLexId, isLexSym, isLexConId, isLexConSym,
- isLexVarId, isLexVarSym :: FAST_STRING -> Bool
+mkLocalName :: Unique -> OccName -> SrcLoc -> Name
+mkLocalName uniq occ loc = Name { n_uniq = uniq, n_sort = Local, n_occ = occ,
+ n_prov = LocalDef loc NotExported }
+ -- 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)
+
+mkImportedLocalName :: Unique -> OccName -> SrcLoc -> Name
+ -- Just the same as mkLocalName, except the provenance is different
+ -- Reason: this flags the name as one that came in from an interface file.
+ -- This is useful when trying to decide which of two type variables
+ -- should 'win' when unifying them.
+ -- NB: this is only for non-top-level names, so we use ImplicitImport
+mkImportedLocalName uniq occ loc = Name { n_uniq = uniq, n_sort = Local, n_occ = occ,
+ n_prov = NonLocalDef ImplicitImport True }
-isLexCon cs = isLexConId cs || isLexConSym cs
-isLexVar cs = isLexVarId cs || isLexVarSym cs
-isLexId cs = isLexConId cs || isLexVarId cs
-isLexSym cs = isLexConSym cs || isLexVarSym cs
+mkGlobalName :: Unique -> Module -> OccName -> Provenance -> Name
+mkGlobalName uniq mod occ prov = Name { n_uniq = uniq, n_sort = Global mod,
+ n_occ = occ, n_prov = prov }
+
+
+mkKnownKeyGlobal :: (RdrName, Unique) -> Name
+mkKnownKeyGlobal (rdr_name, uniq)
+ = mkGlobalName uniq (mkVanillaModule (rdrNameModule rdr_name))
+ (rdrNameOcc rdr_name)
+ systemProvenance
+
+mkSysLocalName :: Unique -> UserFS -> Name
+mkSysLocalName uniq fs = Name { n_uniq = uniq, n_sort = Local,
+ n_occ = mkSrcVarOcc fs, n_prov = systemProvenance }
+
+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_prov = NonLocalDef ImplicitImport True }
+
+mkTopName :: Unique -> Module -> FAST_STRING -> Name
+ -- Make a top-level name; make it Global if top-level
+ -- things should be externally visible; Local otherwise
+ -- This chap is only used *after* the tidyCore phase
+ -- Notably, it is used during STG lambda lifting
+ --
+ -- We have to make sure that the name is globally unique
+ -- and we don't have tidyCore to help us. So we append
+ -- the unique. Hack! Hack!
+mkTopName uniq mod fs
+ = Name { n_uniq = uniq,
+ n_sort = mk_top_sort mod,
+ n_occ = mkSrcVarOcc (_PK_ ((_UNPK_ fs) ++ show uniq)),
+ n_prov = LocalDef noSrcLoc NotExported }
+
+mkIPName :: Unique -> OccName -> Name
+mkIPName uniq occ
+ = Name { n_uniq = uniq,
+ n_sort = Local,
+ n_occ = occ,
+ -- ZZ is this an appropriate provinence?
+ n_prov = SystemProv }
+
+------------------------- Wired in names -------------------------
+
+mkWiredInIdName :: Unique -> Module -> OccName -> Id -> Name
+mkWiredInIdName uniq mod occ id = Name { n_uniq = uniq, n_sort = WiredInId mod id,
+ n_occ = occ, n_prov = SystemProv }
+
+-- mkWiredInTyConName takes a FAST_STRING instead of
+-- an OccName, which is a bit yukky but that's what the
+-- clients find easiest.
+mkWiredInTyConName :: Unique -> Module -> FAST_STRING -> TyCon -> Name
+mkWiredInTyConName uniq mod fs tycon
+ = Name { n_uniq = uniq, n_sort = WiredInTyCon mod tycon,
+ n_occ = mkSrcOccFS tcName fs, n_prov = SystemProv }
--------------
-isLexConId cs
- | _NULL_ cs = False
- | cs == SLIT("[]") = True
- | c == '(' = True -- (), (,), (,,), ...
- | otherwise = isUpper c || isUpperISO c
- where
- c = _HEAD_ cs
+---------------------------------------------------------------------
+mkDerivedName :: (OccName -> OccName)
+ -> Name -- Base name
+ -> Unique -- New unique
+ -> Name -- Result is always a value name
-isLexVarId cs
- | _NULL_ cs = False
- | otherwise = isLower c || isLowerISO c
- where
- c = _HEAD_ cs
+mkDerivedName f name uniq = name {n_uniq = uniq, n_occ = f (n_occ name)}
-isLexConSym cs
- | _NULL_ cs = False
- | otherwise = c == ':'
- || cs == SLIT("->")
- where
- c = _HEAD_ cs
+-- mkUnboundName makes a place-holder Name; it shouldn't be looked at except possibly
+-- during compiler debugging.
+mkUnboundName :: RdrName -> Name
+mkUnboundName rdr_name = mkLocalName unboundKey (rdrNameOcc rdr_name) noSrcLoc
-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
+isUnboundName :: Name -> Bool
+isUnboundName name = name `hasKey` unboundKey
\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) ',' ++ "#)"))
+-- 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
+ -- Give the thing a new OccName, *and*
+ -- record that it's no longer a sys-local
+ -- This is used by the tidy-up pass
+setNameOcc name occ = name {n_occ = occ}
+
+setNameModule :: Name -> Module -> Name
+setNameModule name mod = name {n_sort = set (n_sort name)}
+ where
+ set (Global _) = Global mod
+ set (WiredInId _ id) = WiredInId mod id
+ set (WiredInTyCon _ tycon) = WiredInTyCon mod tycon
\end{code}
%************************************************************************
%* *
-\subsection[Name-pieces-datatypes]{The @OccName@ datatypes}
+\subsection{Setting provenance and visibility
%* *
%************************************************************************
+tidyTopName is applied to top-level names in the final program
+
+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)
+
+In all cases except an exported global, it gives it a new occurrence name.
+
+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}
-data OccName = VarOcc FAST_STRING -- Variables and data constructors
- | TvOcc FAST_STRING -- Type variables
- | TCOcc FAST_STRING -- Type constructors and classes
-
-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)
-prefixOccName prefix (TCOcc s) = TCOcc (prefix _APPEND_ s)
-
--- occNameFlavour is used only to generate good error messages, so it doesn't matter
--- that the VarOcc case isn't mega-efficient. We could have different Occ constructors for
--- data constructors and values, but that makes everything else a bit more complicated.
-occNameFlavour :: OccName -> String
-occNameFlavour (VarOcc s) | isLexConId s = "Data constructor"
- | otherwise = "Value"
-occNameFlavour (TvOcc s) = "Type variable"
-occNameFlavour (TCOcc s) = "Type constructor or class"
-
-isVarOcc, isTCOcc, isTvOcc :: OccName -> Bool
-isVarOcc (VarOcc s) = True
-isVarOcc other = False
-
-isTvOcc (TvOcc s) = True
-isTvOcc other = False
-
-isTCOcc (TCOcc s) = True
-isTCOcc other = False
-
-instance Eq OccName where
- a == b = case (a `compare` b) of { EQ -> True; _ -> False }
- a /= b = case (a `compare` b) of { EQ -> False; _ -> True }
+tidyTopName :: Module -> TidyOccEnv -> Name -> (TidyOccEnv, Name)
+tidyTopName mod env name
+ = (env', name')
+ where
+ (env', occ') = tidyOccName env (n_occ name)
-instance Ord OccName where
- 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
+ name' = Name { n_uniq = n_uniq name, n_sort = mk_top_sort mod,
+ n_occ = occ', n_prov = LocalDef noSrcLoc NotExported }
-(VarOcc s1) `cmpOcc` (VarOcc s2) = s1 `compare` s2
-(VarOcc s1) `cmpOcc` other2 = LT
+mk_top_sort mod | all_toplev_ids_visible = Global mod
+ | otherwise = Local
-(TvOcc s1) `cmpOcc` (VarOcc s2) = GT
-(TvOcc s1) `cmpOcc` (TvOcc s2) = s1 `compare` s2
-(TvOcc s1) `cmpOcc` other = LT
+all_toplev_ids_visible =
+ not opt_OmitInterfacePragmas || -- Pragmas can make them visible
+ opt_EnsureSplittableC -- Splitting requires visiblilty
+\end{code}
+
+
+\begin{code}
+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 provenance of *any* global (SLPJ Jun 97)
+setNameProvenance name prov = name {n_prov = prov}
-(TCOcc s1) `cmpOcc` (TCOcc s2) = s1 `compare` s2
-(TCOcc s1) `cmpOcc` other = GT
+getNameProvenance :: Name -> Provenance
+getNameProvenance name = n_prov name
-instance Outputable OccName where
- ppr = pprOccName
+setNameImportReason :: Name -> ImportReason -> Name
+setNameImportReason name reason
+ = name { n_prov = new_prov }
+ where
+ -- It's important that we don't do the pattern matching
+ -- in the top-level clause, else we get a black hole in
+ -- the renamer. Rather a yukky constraint. There's only
+ -- one call, in RnNames
+ old_prov = n_prov name
+ new_prov = case old_prov of
+ NonLocalDef _ omit -> NonLocalDef reason omit
+ other -> old_prov
\end{code}
%************************************************************************
%* *
-\subsection[Name-datatype]{The @Name@ datatype, and name construction}
+\subsection{Provenance and export info}
%* *
%************************************************************************
-
-\begin{code}
-data Name
- = Local Unique
- (Maybe OccName) -- For ones that started life with a user name
-
- | Global Unique
- Module -- The defining module
- OccName -- Its name in that module
- Provenance -- How it was defined
-\end{code}
-
-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.
\begin{code}
data Provenance
- = NoProvenance
-
- | LocalDef -- Defined locally
+ = 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
+ ImportReason
PrintUnqualified
- | WiredInTyCon TyCon -- There's a wired-in version
- | WiredInId Id -- ...ditto...
+ | SystemProv -- Either (a) a system-generated local with
+ -- a v short name OccName
+ -- or (b) a known-key global which should have a proper
+ -- provenance attached by the renamer
+\end{code}
+
+Sys-provs are only used internally. When the compiler generates (say)
+a fresh desguar variable it always calls it "ds", and of course it gets
+a fresh unique. But when printing -ddump-xx dumps, we must print it with
+its unique, because there'll be a lot of "ds" variables.
+
+Names with SystemProv differ in the following ways:
+ a) locals have unique attached when printing dumps
+ b) unifier eliminates sys tyvars in favour of user provs where possible
+ c) renamer replaces SystemProv with a better one
+
+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.
+
+\begin{code}
+data ImportReason
+ = UserImport Module SrcLoc Bool -- Imported from module M on line L
+ -- Note the M may well not be the defining module
+ -- for this thing!
+ -- The Bool is true iff the thing was named *explicitly* in the import spec,
+ -- rather than being imported as part of a group; e.g.
+ -- import B
+ -- import C( T(..) )
+ -- Here, everything imported by B, and the constructors of T
+ -- are not named explicitly; only T is named explicitly.
+ -- This info is used when warning of unused names.
+
+ | ImplicitImport -- Imported implicitly for some other reason
+
type PrintUnqualified = Bool -- True <=> the unqualified name of this thing is
-- in scope in this module, so print it
-- unqualified in error messages
+
+data ExportFlag = Exported | NotExported
\end{code}
Something is "Exported" if it may be mentioned by another module without
Id's unfolding in the interface file, in which case the local Id goes
out too.
-\begin{code}
-data ExportFlag = Exported | NotExported
-\end{code}
\begin{code}
-mkLocalName :: Unique -> OccName -> Name
-mkLocalName uniq occ = Local uniq (Just occ)
-
-mkGlobalName :: Unique -> Module -> OccName -> Provenance -> Name
-mkGlobalName = Global
-
-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)
+systemProvenance :: Provenance
+systemProvenance = SystemProv
-mkWiredInTyConName :: Unique -> Module -> FAST_STRING -> TyCon -> Name
-mkWiredInTyConName uniq mod occ tycon
- = Global uniq mod (TCOcc occ) (WiredInTyCon tycon)
-
-
-mkCompoundName :: (OccName -> OccName)
- -> Unique -- New unique
- -> Name -- Base name
- -> Name -- Result is always a value name
-
-mkCompoundName f uniq (Global _ mod occ prov)
- = Global uniq mod (f occ) prov
-
-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 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) = LocalDef noSrcLoc NotExported
+-- pprNameProvenance is used in error messages to say where a name came from
+pprNameProvenance :: Name -> SDoc
+pprNameProvenance name = pprProvenance (getNameProvenance name)
--- 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 ) u = Local u n
-changeUnique (Global _ mod occ prov) u = Global u mod occ prov
+pprProvenance :: Provenance -> SDoc
+pprProvenance SystemProv = ptext SLIT("System")
+pprProvenance (LocalDef loc _) = ptext SLIT("defined at") <+> ppr loc
+pprProvenance (NonLocalDef ImplicitImport _)
+ = ptext SLIT("implicitly imported")
+pprProvenance (NonLocalDef (UserImport mod loc _) _)
+ = ptext SLIT("imported from") <+> ppr mod <+> ptext SLIT("at") <+> ppr loc
\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)
-
-For nested things it localises Global names.
-
-In all cases except an exported global, it gives it a new occurrence name.
-
-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 -- 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)
-
-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}
%************************************************************************
%* *
\begin{code}
nameUnique :: Name -> Unique
-nameModAndOcc :: Name -> (Module, OccName) -- Globals only
nameOccName :: Name -> OccName
nameModule :: Name -> Module
nameSrcLoc :: Name -> SrcLoc
isLocallyDefinedName :: Name -> Bool
-isExportedName :: Name -> Bool
+isUserExportedName :: Name -> Bool
isWiredInName :: Name -> Bool
isLocalName :: Name -> Bool
isGlobalName :: Name -> Bool
-nameUnique (Local u _) = u
-nameUnique (Global u _ _ _) = u
+hashName :: Name -> Int
+hashName name = IBOX( u2i (nameUnique name) )
+
+nameUnique name = n_uniq name
+nameOccName name = n_occ name
+
+nameModule name =
+ case n_sort name of
+ Local -> pprPanic "nameModule" (ppr name)
+ x -> nameSortModule x
-nameOccName (Local _ (Just occ)) = occ
-nameOccName (Local uniq Nothing) = pprPanic "nameOccName" (ppr uniq)
-nameOccName (Global _ _ occ _) = occ
+nameSortModule (Global mod) = mod
+nameSortModule (WiredInId mod _) = mod
+nameSortModule (WiredInTyCon mod _) = mod
-nameModule (Global _ mod occ _) = mod
+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_sort = Local, n_occ = occ }) = mkRdrUnqual occ
+nameRdrName (Name { n_sort = sort, n_occ = occ }) = mkRdrQual (moduleName (nameSortModule sort)) occ
-nameModAndOcc (Global _ mod occ _) = (mod,occ)
+ifaceNameRdrName :: Name -> RdrName
+-- Makes a qualified naem for imported things,
+-- and an unqualified one for local things
+ifaceNameRdrName n | isLocallyDefined n = mkRdrUnqual (nameOccName n)
+ | otherwise = mkRdrQual (moduleName (nameModule n)) (nameOccName n)
-isExportedName (Global _ _ _ (LocalDef _ Exported)) = True
-isExportedName other = False
+isUserExportedName (Name { n_prov = LocalDef _ Exported }) = True
+isUserExportedName other = False
-nameSrcLoc (Local _ _) = noSrcLoc
-nameSrcLoc (Global _ _ _ (LocalDef loc _)) = loc
-nameSrcLoc (Global _ _ _ (NonLocalDef loc _ _)) = loc
-nameSrcLoc (Global _ _ _ (WiredInTyCon _)) = mkBuiltinSrcLoc
-nameSrcLoc (Global _ _ _ (WiredInId _)) = mkBuiltinSrcLoc
-nameSrcLoc other = noSrcLoc
+isUserImportedExplicitlyName (Name { n_prov = NonLocalDef (UserImport _ _ explicit) _ }) = explicit
+isUserImportedExplicitlyName other = False
+
+isUserImportedName (Name { n_prov = NonLocalDef (UserImport _ _ _) _ }) = True
+isUserImportedName other = False
+
+maybeUserImportedFrom (Name { n_prov = NonLocalDef (UserImport m _ _) _ }) = Just m
+maybeUserImportedFrom other = Nothing
+
+isDllName :: Name -> Bool
+ -- Does this name refer to something in a different DLL?
+isDllName nm = not opt_Static &&
+ not (isLocallyDefinedName nm) &&
+ not (isLocalModule (nameModule nm))
+
+nameSrcLoc name = provSrcLoc (n_prov name)
+
+provSrcLoc (LocalDef loc _) = loc
+provSrcLoc (NonLocalDef (UserImport _ loc _) _) = loc
+provSrcLoc other = noSrcLoc
-isLocallyDefinedName (Local _ _) = True
-isLocallyDefinedName (Global _ _ _ (LocalDef _ _)) = True
-isLocallyDefinedName other = False
+isLocallyDefinedName (Name {n_sort = Local}) = True -- Local (might have SystemProv)
+isLocallyDefinedName (Name {n_prov = LocalDef _ _}) = True -- Global, but defined here
+isLocallyDefinedName other = False -- Other
-- 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 (Name {n_sort = WiredInTyCon _ _}) = True
+isWiredInName (Name {n_sort = WiredInId _ _}) = True
+isWiredInName _ = False
maybeWiredInIdName :: Name -> Maybe Id
-maybeWiredInIdName (Global _ _ _ (WiredInId id)) = Just id
-maybeWiredInIdName other = Nothing
+maybeWiredInIdName (Name {n_sort = WiredInId _ id}) = Just id
+maybeWiredInIdName other = Nothing
maybeWiredInTyConName :: Name -> Maybe TyCon
-maybeWiredInTyConName (Global _ _ _ (WiredInTyCon tc)) = Just tc
-maybeWiredInTyConName other = Nothing
-
+maybeWiredInTyConName (Name {n_sort = WiredInTyCon _ tc}) = Just tc
+maybeWiredInTyConName other = Nothing
-isLocalName (Local _ _) = True
-isLocalName _ = False
-isSysLocalName (Local _ Nothing) = True
-isSysLocalName other = False
+isLocalName (Name {n_sort = Local}) = True
+isLocalName _ = False
-isGlobalName (Global _ _ _ _) = True
-isGlobalName other = False
+isGlobalName (Name {n_sort = Local}) = False
+isGlobalName other = True
-- 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
+
+hasBetterProv :: Name -> Name -> Bool
+-- Choose
+-- a local thing over an imported thing
+-- a user-imported thing over a non-user-imported thing
+-- an explicitly-imported thing over an implicitly imported thing
+hasBetterProv n1 n2
+ = case (n_prov n1, n_prov n2) of
+ (LocalDef _ _, _ ) -> True
+ (NonLocalDef (UserImport _ _ True) _, _ ) -> True
+ (NonLocalDef (UserImport _ _ _ ) _, NonLocalDef ImplicitImport _) -> True
+ other -> False
+
+isSystemName (Name {n_prov = SystemProv}) = True
+isSystemName other = False
\end{code}
%************************************************************************
\begin{code}
-cmpName n1 n2 = c n1 n2
- where
- c (Local u1 _) (Local u2 _) = compare u1 u2
- c (Local _ _) _ = LT
- c (Global u1 _ _ _) (Global u2 _ _ _) = compare u1 u2
- c (Global _ _ _ _) _ = GT
+cmpName n1 n2 = n_uniq n1 `compare` n_uniq n2
\end{code}
\begin{code}
a /= b = case (a `compare` b) of { EQ -> False; _ -> True }
instance Ord Name where
- 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 -> 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
%************************************************************************
%* *
-\subsection[Special-Names]{Special Kinds of names}
+\subsection{Name environment}
%* *
%************************************************************************
-Here's our convention for splitting up the object file name space:
-
- _d... dictionary identifiers
- _g... externally visible (non-user visible) names
-
- _m... default methods
- _n... default methods (encoded symbols, eg. <= becomes _nle)
-
- _p... superclass selectors
-
- _w... workers
- _v... workers (encoded symbols)
-
- _x... local variables
-
- _u... user-defined names that previously began with '_'
-
- _[A-Z]... compiler-generated tycons/datacons (namely dictionary
- constructors)
-
- __.... 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'
+type NameEnv a = UniqFM a -- Domain is Name
+
+emptyNameEnv :: NameEnv a
+nameEnvElts :: NameEnv a -> [a]
+addToNameEnv_C :: (a->a->a) -> NameEnv a -> Name -> a -> NameEnv a
+addToNameEnv :: NameEnv a -> Name -> a -> NameEnv a
+addListToNameEnv :: NameEnv a -> [(Name,a)] -> NameEnv a
+plusNameEnv :: NameEnv a -> NameEnv a -> NameEnv a
+plusNameEnv_C :: (a->a->a) -> NameEnv a -> NameEnv a -> NameEnv a
+extendNameEnv :: NameEnv a -> [(Name,a)] -> NameEnv a
+lookupNameEnv :: NameEnv a -> Name -> Maybe a
+delFromNameEnv :: NameEnv a -> Name -> NameEnv a
+elemNameEnv :: Name -> NameEnv a -> Bool
+unitNameEnv :: Name -> a -> NameEnv a
+
+emptyNameEnv = emptyUFM
+nameEnvElts = eltsUFM
+addToNameEnv_C = addToUFM_C
+addToNameEnv = addToUFM
+addListToNameEnv = addListToUFM
+plusNameEnv = plusUFM
+plusNameEnv_C = plusUFM_C
+extendNameEnv = addListToUFM
+lookupNameEnv = lookupUFM
+delFromNameEnv = delFromUFM
+elemNameEnv = elemUFM
+unitNameEnv = unitUFM
\end{code}
+
%************************************************************************
%* *
\subsection{Pretty printing}
-- When printing interfaces, all Locals have been given nice print-names
ppr name = pprName name
-pprName name
+pprName (Name {n_sort = Local, n_uniq = uniq, n_occ = occ, n_prov = prov})
+ -- Locals
= 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 '?'
+ if codeStyle sty then
+ pprUnique uniq -- When printing in code we required all names to
+ -- be globally unique; for example, we use this identifier
+ -- for the closure name. So we just print the unique alone.
+ else
+ pprOccName occ <> pp_local_extra sty uniq
+ where
+ sys_local = case prov of
+ SystemProv -> True
+ other -> False
--- 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
+ pp_local_extra sty uniq
+ | sys_local = underscore <> pprUnique uniq -- Must print uniques for sys_locals
+ | debugStyle sty = text "{-" <> pprUnique uniq <> text "-}"
+ | otherwise = empty
-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")
+
+pprName (Name {n_sort = sort, n_uniq = uniq, n_occ = occ, n_prov = prov})
+ -- Globals, and wired in things
+ = getPprStyle $ \ sty ->
+ if codeStyle sty then
+ ppr mod <> underscore <> ppr occ
+ else
+ pp_mod_dot sty <> ppr occ <> pp_global_debug sty uniq prov
+ where
+ mod = nameSortModule sort
+
+ pp_mod_dot sty
+ = case prov of
+ SystemProv -> pp_qual mod user_sty
+ -- Hack alert! Omit the qualifier on SystemProv things in user style
+ -- I claim such SystemProv things will also be WiredIn things.
+ -- We can't get the omit flag right
+ -- on wired in tycons etc (sigh) so we just leave it out in user style,
+ -- and hope that leaving it out isn't too consfusing.
+ -- (e.g. if the programmer hides Bool and redefines it. If so, use -dppr-debug.)
+
+ LocalDef _ _ -> pp_qual mod (user_sty || iface_sty)
+
+ NonLocalDef (UserImport imp_mod _ _) omit
+ | user_sty -> pp_qual imp_mod omit
+ | otherwise -> pp_qual mod False
+ NonLocalDef ImplicitImport omit -> pp_qual mod (user_sty && omit)
+ where
+ user_sty = userStyle sty
+ iface_sty = ifaceStyle sty
+
+ pp_qual mod omit_qual
+ | omit_qual = empty
+ | otherwise = pprModule mod <> dot
+
+ pp_global_debug sty uniq prov
+ | debugStyle sty = hcat [text "{-", pprUnique uniq, prov_p prov, text "-}"]
+ | otherwise = empty
+
+ prov_p prov | opt_PprStyle_NoPrags = empty
+ | otherwise = comma <> pp_prov prov
+
+pp_prov (LocalDef _ Exported) = char 'x'
+pp_prov (LocalDef _ NotExported) = char 'l'
+pp_prov (NonLocalDef ImplicitImport _) = char 'j'
+pp_prov (NonLocalDef (UserImport _ _ True ) _) = char 'I' -- Imported by name
+pp_prov (NonLocalDef (UserImport _ _ False) _) = char 'i' -- Imported by ..
+pp_prov SystemProv = char 's'
\end{code}
\begin{code}
class NamedThing a where
- getOccName :: a -> OccName -- Even RdrNames can do this!
+ getOccName :: a -> OccName
getName :: a -> Name
getOccName n = nameOccName (getName n) -- Default method
\end{code}
\begin{code}
-modAndOcc :: NamedThing a => a -> (Module, OccName)
getSrcLoc :: NamedThing a => a -> SrcLoc
isLocallyDefined :: NamedThing a => a -> Bool
-isExported :: NamedThing a => a -> Bool
getOccString :: NamedThing a => a -> String
+toRdrName :: NamedThing a => a -> RdrName
-modAndOcc = nameModAndOcc . getName
-isExported = isExportedName . getName
getSrcLoc = nameSrcLoc . getName
isLocallyDefined = isLocallyDefinedName . getName
-getOccString x = _UNPK_ (occNameString (getOccName x))
+getOccString x = occNameString (getOccName x)
+toRdrName = ifaceNameRdrName . getName
\end{code}
\begin{code}
-{-# SPECIALIZE isLocallyDefined
- :: Name -> Bool
- #-}
+{-# SPECIALIZE isLocallyDefined :: Name -> Bool #-}
\end{code}