diff options
author | simonpj <unknown> | 1998-12-18 17:42:39 +0000 |
---|---|---|
committer | simonpj <unknown> | 1998-12-18 17:42:39 +0000 |
commit | 7e602b0a11e567fcb035d1afd34015aebcf9a577 (patch) | |
tree | 54ca13c3ec0704e343b68d0d313a29f53d6c3855 /ghc/compiler/basicTypes/Name.lhs | |
parent | 139f0fd30e19f934aa51885a52b8e5d7c24ee460 (diff) | |
download | haskell-7e602b0a11e567fcb035d1afd34015aebcf9a577.tar.gz |
[project @ 1998-12-18 17:40:31 by simonpj]
Another big commit from Simon. Actually, the last one
didn't all go into the main trunk; because of a CVS glitch it
ended up in the wrong branch.
So this commit includes:
* Scoped type variables
* Warnings for unused variables should work now (they didn't before)
* Simplifier improvements:
- Much better treatment of strict arguments
- Better treatment of bottoming Ids
- No need for w/w split for fns that are merely strict
- Fewer iterations needed, I hope
* Less gratuitous renaming in interface files and abs C
* OccName is a separate module, and is an abstract data type
I think the whole Prelude and Exts libraries compile correctly.
Something isn't quite right about typechecking existentials though.
Diffstat (limited to 'ghc/compiler/basicTypes/Name.lhs')
-rw-r--r-- | ghc/compiler/basicTypes/Name.lhs | 735 |
1 files changed, 259 insertions, 476 deletions
diff --git a/ghc/compiler/basicTypes/Name.lhs b/ghc/compiler/basicTypes/Name.lhs index 5fc667cfa3..a84e626f98 100644 --- a/ghc/compiler/basicTypes/Name.lhs +++ b/ghc/compiler/basicTypes/Name.lhs @@ -5,33 +5,20 @@ \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, mkSysLocalName, mkTopName, + mkDerivedName, mkGlobalName, mkWiredInIdName, mkWiredInTyConName, maybeWiredInIdName, maybeWiredInTyConName, isWiredInName, - nameUnique, changeUnique, setNameProvenance, getNameProvenance, - setNameVisibility, mkNameVisible, - nameOccName, nameModule, + nameUnique, setNameUnique, setNameProvenance, getNameProvenance, + tidyTopName, mkNameVisible, + nameOccName, nameModule, setNameOcc, isExportedName, nameSrcLoc, isLocallyDefinedName, @@ -40,14 +27,9 @@ module Name ( pprNameProvenance, - -- Special Names - dictNamePrefix, mkSuperDictSelName, mkWorkerName, - mkDefaultMethodName, mkClassTyConStr, mkClassDataConStr, - -- Misc - Provenance(..), pprProvenance, - ExportFlag(..), - PrintUnqualified, + Provenance(..), ImportReason(..), pprProvenance, + ExportFlag(..), PrintUnqualified, -- Class NamedThing and overloaded friends NamedThing(..), @@ -60,177 +42,19 @@ module Name ( import {-# SOURCE #-} Var ( Id ) import {-# SOURCE #-} TyCon ( TyCon ) -import CStrings ( identToC ) -import PrelMods ( pREL_BASE, pREL_TUP, pREL_GHC ) +import OccName -- All of it import CmdLineOpts ( opt_PprStyle_NoPrags, opt_OmitInterfacePragmas, opt_EnsureSplittableC ) -import BasicTypes ( Module, IfaceFlavour(..), moduleString, pprModule ) +import BasicTypes ( IfaceFlavour(..) ) 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} - - -%************************************************************************ -%* * -\subsection[Name-pieces-datatypes]{The @OccName@ datatypes} -%* * -%************************************************************************ - -\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 } - -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 - -(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 `compare` s2 -(TvOcc s1) `cmpOcc` other = LT - -(TCOcc s1) `cmpOcc` (TCOcc s2) = s1 `compare` s2 -(TCOcc s1) `cmpOcc` other = GT - -instance Outputable OccName where - ppr = pprOccName -\end{code} - - -%************************************************************************ -%* * \subsection[Name-datatype]{The @Name@ datatype, and name construction} %* * %************************************************************************ @@ -238,7 +62,10 @@ instance Outputable OccName where \begin{code} data Name = Local Unique - (Maybe OccName) -- For ones that started life with a user name + OccName -- How to print it + Bool -- True <=> this is a "sys-local" + -- see notes just below + | Global Unique Module -- The defining module @@ -246,117 +73,103 @@ data Name Provenance -- How it was defined \end{code} +Sys-locals 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. That debug +printing issue is the ONLY way in which sys-locals are different. I think. + +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 ordinary locals +If any desugarer sys-locals have survived that far, they get changed to +"ds1", "ds2", etc. + 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 - 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 -warning. The crucial thing about Exported things is that they must -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 - - - dfuns from instance decls - -Being Exported is *not* the same as finally appearing in the .o file's -symbol table. For example, a local Id may be mentioned in an Exported -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) +mkLocalName uniq occ = Local uniq occ False + -- NB: You might worry that after lots of huffing and + -- puffing we might end up with two local names with distinct + -- uniques, but the same OccName. Indeed we can, but that's ok + -- * the insides of the compiler don't care: they use the Unique + -- * when printing for -ddump-xxx you can switch on -dppr-debug to get the + -- uniques if you get confused + -- * for interface files we tidyCore first, which puts the uniques + -- into the print name (see setNameVisibility below) mkGlobalName :: Unique -> Module -> OccName -> Provenance -> Name mkGlobalName = Global -mkSysLocalName :: Unique -> Name -mkSysLocalName uniq = Local uniq Nothing +mkSysLocalName :: Unique -> FAST_STRING -> Name +mkSysLocalName uniq fs = Local uniq (varOcc fs) 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 + | all_toplev_ids_visible = Global uniq mod occ (LocalDef noSrcLoc NotExported) + | otherwise = Local uniq occ False + where + occ = varOcc (_PK_ ((_UNPK_ fs) ++ show uniq)) -mkWiredInIdName :: Unique -> Module -> FAST_STRING -> Id -> Name -mkWiredInIdName uniq mod occ id - = Global uniq mod (VarOcc occ) (WiredInId id) +mkWiredInIdName :: Unique -> Module -> OccName -> Id -> Name +mkWiredInIdName uniq mod occ id = Global uniq mod occ (WiredInId id) +-- 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 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)) + = Global uniq mod (tcOcc occ) (WiredInTyCon tycon) -mkCompoundName f uniq (Local _ Nothing) - = Local uniq Nothing +mkDerivedName :: (OccName -> OccName) + -> Name -- Base name + -> Unique -- New unique + -> Name -- Result is always a value name -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 +mkDerivedName f (Global _ mod occ prov) uniq = Global uniq mod (f occ) prov +mkDerivedName f (Local _ occ sys) uniq = Local uniq (f occ) sys -- 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 +setNameUnique (Local _ occ sys) u = Local u occ sys +setNameUnique (Global _ mod occ prov) u = Global u mod occ prov + +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 (Global uniq mod _ prov) occ = Global uniq mod occ prov +setNameOcc (Local uniq _ sys) occ = Local uniq occ False \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) +%************************************************************************ +%* * +\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) -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 @@ -384,41 +197,126 @@ are exported. But also: top-level defns externally visible \begin{code} -setNameVisibility :: Maybe Module -> Unique -> Name -> Name +tidyTopName :: Module -> TidyOccEnv -> Name -> (TidyOccEnv, Name) +tidyTopName mod env name + | isExported name = (env, name) -- Don't fiddle with an exported name + -- It should be in the TidyOccEnv already + | otherwise = (env', name') + where + prov = getNameProvenance name + uniq = nameUnique name + (env', occ') = tidyOccName env (nameOccName 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 + name' | all_toplev_ids_visible = Global uniq mod occ' prov + | otherwise = Local uniq occ' False -setNameVisibility maybe_mod uniq name@(Global _ _ _ _) - = name -- Otherwise don't fiddle with Global +all_toplev_ids_visible = + not opt_OmitInterfacePragmas || -- Pragmas can make them visible + opt_EnsureSplittableC -- Splitting requires visiblilty +\end{code} -setNameVisibility (Just mod) uniq (Local _ _) - | all_toplev_ids_visible - = Global uniq mod -- Globalise Local name - (uniqToOccName uniq) - (LocalDef noSrcLoc NotExported) +\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 (Global uniq mod occ _) prov = Global uniq mod occ prov +setNameProvenance other_name prov = other_name -setNameVisibility maybe_mod uniq (Local _ _) - = Local uniq Nothing -- New unique for Local; zap its occ +getNameProvenance :: Name -> Provenance +getNameProvenance (Global uniq mod occ prov) = prov +getNameProvenance (Local _ _ _) = LocalDef noSrcLoc NotExported +\end{code} +\begin{code} -- 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) +mkNameVisible mod occ_uniq nm@(Local uniq occ _) + = Global uniq mod occ (LocalDef noSrcLoc Exported) +\end{code} -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 +%************************************************************************ +%* * +\subsection{Provenance and export info} +%* * +%************************************************************************ -all_toplev_ids_visible = - not opt_OmitInterfacePragmas || -- Pragmas can make them visible - opt_EnsureSplittableC -- Splitting requires visiblilty +\begin{code} +data Provenance + = NoProvenance + + | LocalDef -- Defined locally + SrcLoc -- Defn site + ExportFlag -- Whether it's exported + + | NonLocalDef -- Defined non-locally + ImportReason + IfaceFlavour -- Whether the defn site is an .hi-boot file + PrintUnqualified + + | WiredInTyCon TyCon -- There's a wired-in version + | WiredInId Id -- ...ditto... + +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 +warning. The crucial thing about Exported things is that they must +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 + + - dfuns from instance decls + +Being Exported is *not* the same as finally appearing in the .o file's +symbol table. For example, a local Id may be mentioned in an Exported +Id's unfolding in the interface file, in which case the local Id goes +out too. + + +\begin{code} +-- pprNameProvenance is used in error messages to say where a name came from +pprNameProvenance :: Name -> SDoc +pprNameProvenance name = pprProvenance (getNameProvenance name) + +pprProvenance :: Provenance -> SDoc +pprProvenance NoProvenance = ptext SLIT("No provenance") +pprProvenance (LocalDef loc _) = ptext SLIT("defined at") <+> ppr loc +pprProvenance (WiredInTyCon tc) = ptext SLIT("Wired-in tycon") +pprProvenance (WiredInId id) = ptext SLIT("Wired-in id") +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} + %************************************************************************ %* * \subsection{Predicates and selectors} @@ -440,12 +338,11 @@ isExternallyVisibleName :: Name -> Bool -nameUnique (Local u _) = u +nameUnique (Local u _ _) = u nameUnique (Global u _ _ _) = u -nameOccName (Local _ (Just occ)) = occ -nameOccName (Local uniq Nothing) = pprPanic "nameOccName" (ppr uniq) -nameOccName (Global _ _ occ _) = occ +nameOccName (Local _ occ _) = occ +nameOccName (Global _ _ occ _) = occ nameModule (Global _ mod occ _) = mod @@ -454,14 +351,13 @@ nameModAndOcc (Global _ mod occ _) = (mod,occ) isExportedName (Global _ _ _ (LocalDef _ Exported)) = True isExportedName 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 +nameSrcLoc (Global _ _ _ (LocalDef loc _)) = loc +nameSrcLoc (Global _ _ _ (NonLocalDef (UserImport _ 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 @@ -482,11 +378,11 @@ 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 +isSysLocalName (Local _ _ sys) = sys +isSysLocalName other = False isGlobalName (Global _ _ _ _) = True isGlobalName other = False @@ -507,10 +403,10 @@ isExternallyVisibleName name = isGlobalName name \begin{code} cmpName n1 n2 = c n1 n2 where - c (Local u1 _) (Local u2 _) = compare u1 u2 - c (Local _ _) _ = LT + c (Local u1 _ _) (Local u2 _ _) = compare u1 u2 + c (Local _ _ _) _ = LT c (Global u1 _ _ _) (Global u2 _ _ _) = compare u1 u2 - c (Global _ _ _ _) _ = GT + c (Global _ _ _ _) _ = GT \end{code} \begin{code} @@ -535,103 +431,6 @@ instance NamedThing Name where %************************************************************************ %* * -\subsection[Special-Names]{Special Kinds of names} -%* * -%************************************************************************ - -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' -\end{code} - -%************************************************************************ -%* * \subsection{Pretty printing} %* * %************************************************************************ @@ -641,76 +440,62 @@ instance Outputable Name where -- When printing interfaces, all Locals have been given nice print-names ppr name = pprName name -pprName name +pprName (Local uniq occ sys_local) = 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 + pp_local_extra sty uniq + | sys_local = underscore <> pprUnique uniq -- Must print uniques for sys_locals + | debugStyle sty = text "{-" <> pprUnique uniq <> text "-}" + | otherwise = empty --- 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") +pprName (Global uniq mod occ prov) + = 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 + pp_mod_dot sty + = 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 + where + user_sty = userStyle sty + iface_sty = ifaceStyle sty + + pp_qual sep omit_qual + | omit_qual = empty + | otherwise = pprModule mod <> sep + + pp_hif HiFile = dot -- Vanilla case + pp_hif HiBootFile = text "!" -- M!t indicates a name imported from a .hi-boot interface + + 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 'i' +pp_prov (NonLocalDef explicitimport _ _) = char 'I' +pp_prov (WiredInTyCon _) = char 'W' +pp_prov (WiredInId _) = char 'w' +pp_prov NoProvenance = char '?' \end{code} @@ -739,11 +524,9 @@ modAndOcc = nameModAndOcc . getName isExported = isExportedName . getName getSrcLoc = nameSrcLoc . getName isLocallyDefined = isLocallyDefinedName . getName -getOccString x = _UNPK_ (occNameString (getOccName x)) +getOccString x = occNameString (getOccName x) \end{code} \begin{code} -{-# SPECIALIZE isLocallyDefined - :: Name -> Bool - #-} +{-# SPECIALIZE isLocallyDefined :: Name -> Bool #-} \end{code} |