X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2FbasicTypes%2FName.lhs;h=1e1fb31f846afd7ed2bbf709d9ecc7192ed99d17;hb=ac10f8408520a30e8437496d320b8b86afda2e8f;hp=4a8f45f2846c87f1bbb10eb1b40f2b21fc948cea;hpb=370e75dd765fc764b318311f96285a1c43669886;p=ghc-hetmet.git diff --git a/ghc/compiler/basicTypes/Name.lhs b/ghc/compiler/basicTypes/Name.lhs index 4a8f45f..1e1fb31 100644 --- a/ghc/compiler/basicTypes/Name.lhs +++ b/ghc/compiler/basicTypes/Name.lhs @@ -10,49 +10,39 @@ module Name ( -- The Name type Name, -- Abstract - mkLocalName, mkImportedLocalName, mkSysLocalName, mkCCallName, - mkTopName, mkIPName, - mkDerivedName, mkGlobalName, mkKnownKeyGlobal, mkWiredInName, - - nameUnique, setNameUnique, setLocalNameSort, - tidyTopName, - nameOccName, nameModule, setNameOcc, nameRdrName, setNameModuleAndLoc, - toRdrName, hashName, - - isUserExportedName, - nameSrcLoc, isLocallyDefinedName, isDllName, - - isSystemName, isLocalName, isGlobalName, isExternallyVisibleName, - isTyVarName, + BuiltInSyntax(..), + mkInternalName, mkSystemName, + mkSystemVarName, mkSysTvName, + mkFCallName, mkIPName, + mkExternalName, mkWiredInName, + + nameUnique, setNameUnique, + nameOccName, nameModule, nameModule_maybe, + tidyNameOcc, + hashName, localiseName, + + nameSrcLoc, nameParent, nameParent_maybe, isImplicitName, + + isSystemName, isInternalName, isExternalName, + isTyVarName, isWiredInName, isBuiltInSyntax, + wiredInNameTyThing_maybe, + nameIsLocalOrFrom, - -- Environment - NameEnv, mkNameEnv, - emptyNameEnv, unitNameEnv, nameEnvElts, - extendNameEnv_C, extendNameEnv, - plusNameEnv, plusNameEnv_C, extendNameEnv, extendNameEnvList, - lookupNameEnv, lookupNameEnv_NF, delFromNameEnv, elemNameEnv, - - -- Class NamedThing and overloaded friends NamedThing(..), - getSrcLoc, isLocallyDefined, getOccString, toRdrName + getSrcLoc, getOccString ) where #include "HsVersions.h" +import {-# SOURCE #-} TypeRep( TyThing ) + import OccName -- All of it -import Module ( Module, moduleName, pprModule, mkVanillaModule, - isModuleInThisPackage ) -import RdrName ( RdrName, mkRdrQual, mkRdrUnqual, rdrNameOcc, - rdrNameModule ) -import CmdLineOpts ( opt_Static, opt_PprStyle_NoPrags, - opt_OmitInterfacePragmas, opt_EnsureSplittableC ) - -import SrcLoc ( builtinSrcLoc, noSrcLoc, SrcLoc ) -import Unique ( Unique, Uniquable(..), u2i, pprUnique ) -import Maybes ( expectJust ) -import FastTypes -import UniqFM +import Module ( Module, moduleFS ) +import SrcLoc ( noSrcLoc, wiredInSrcLoc, SrcLoc ) +import Unique ( Unique, Uniquable(..), getKey, pprUnique ) +import Maybes ( orElse, isJust ) +import FastString ( FastString, zEncodeFS ) import Outputable \end{code} @@ -65,37 +55,50 @@ import Outputable \begin{code} data Name = Name { n_sort :: NameSort, -- What sort of name it is - n_occ :: OccName, -- Its occurrence name + n_occ :: !OccName, -- Its occurrence name n_uniq :: Unique, - n_loc :: SrcLoc -- Definition site + n_loc :: !SrcLoc -- Definition site } -data NameSort - = Global Module -- (a) TyCon, Class, their derived Ids, dfun Id - -- (b) imported Id +-- NOTE: we make the n_loc field strict to eliminate some potential +-- (and real!) space leaks, due to the fact that we don't look at +-- the SrcLoc in a Name all that often. - | Exported -- An exported Ids defined in the module being compiled +data NameSort + = External Module (Maybe Name) + -- (Just parent) => this Name is a subordinate name of 'parent' + -- e.g. data constructor of a data type, method of a class + -- Nothing => not a subordinate + + | WiredIn Module (Maybe Name) TyThing BuiltInSyntax + -- A variant of External, for wired-in things - | Local -- A user-defined, but non-exported Id or TyVar, + | Internal -- A user-defined Id or TyVar -- defined in the module being compiled | System -- A system-defined Id or TyVar. Typically the -- OccName is very uninformative (like 's') + +data BuiltInSyntax = BuiltInSyntax | UserSyntax +-- BuiltInSyntax is for things like (:), [], tuples etc, +-- which have special syntactic forms. They aren't "in scope" +-- as such. \end{code} Notes about the NameSorts: -1. An Exported Id is changed to Global right at the - end in the tidyCore pass, so that an importer sees a Global - Similarly, Local Ids that are visible to an importer (e.g. when - optimisation is on) are changed to Globals. +1. Initially, top-level Ids (including locally-defined ones) get External names, + and all other local Ids get Internal names -2. Things with a @Global@ name are given C static labels, so they finally +2. Things with a External 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. + must be made @External@ first. -3. A System Name differs in the following ways: +3. In the tidy-core phase, a External that is not visible to an importer + is changed to Internal, and a Internal that is visible is changed to External + +4. A System Name differs in the following ways: a) has unique attached when printing dumps b) unifier eliminates sys tyvars in favour of user provs where possible @@ -105,6 +108,14 @@ Notes about the NameSorts: If any desugarer sys-locals have survived that far, they get changed to "ds1", "ds2", etc. +Built-in syntax => It's a syntactic form, not "in scope" (e.g. []) + +Wired-in thing => The thing (Id, TyCon) is fully known to the compiler, + not read from an interface file. + E.g. Bool, True, Int, Float, and many others + +All built-in syntax is for wired-in things. + \begin{code} nameUnique :: Name -> Unique nameOccName :: Name -> OccName @@ -114,32 +125,57 @@ nameSrcLoc :: Name -> SrcLoc nameUnique name = n_uniq name nameOccName name = n_occ name nameSrcLoc name = n_loc name -nameModule (Name { n_sort = Global mod }) = mod -nameModule name = pprPanic "nameModule" (ppr name) \end{code} \begin{code} -isLocallyDefinedName :: Name -> Bool -isUserExportedName :: Name -> Bool -isLocalName :: Name -> Bool -- Not globala -isGlobalName :: Name -> Bool -isSystemName :: Name -> Bool -isExternallyVisibleName :: Name -> Bool +nameIsLocalOrFrom :: Module -> Name -> Bool +isInternalName :: Name -> Bool +isExternalName :: Name -> Bool +isSystemName :: Name -> Bool +isWiredInName :: Name -> Bool + +isWiredInName (Name {n_sort = WiredIn _ _ _ _}) = True +isWiredInName other = False + +wiredInNameTyThing_maybe :: Name -> Maybe TyThing +wiredInNameTyThing_maybe (Name {n_sort = WiredIn _ _ thing _}) = Just thing +wiredInNameTyThing_maybe other = Nothing + +isBuiltInSyntax (Name {n_sort = WiredIn _ _ _ BuiltInSyntax}) = True +isBuiltInSyntax other = False + +isExternalName (Name {n_sort = External _ _}) = True +isExternalName (Name {n_sort = WiredIn _ _ _ _}) = True +isExternalName other = False + +isInternalName name = not (isExternalName name) -isGlobalName (Name {n_sort = Global _}) = True -isGlobalName other = False +nameParent_maybe :: Name -> Maybe Name +nameParent_maybe (Name {n_sort = External _ p}) = p +nameParent_maybe (Name {n_sort = WiredIn _ p _ _}) = p +nameParent_maybe other = Nothing -isLocalName name = not (isGlobalName name) +nameParent :: Name -> Name +nameParent name = case nameParent_maybe name of + Just parent -> parent + Nothing -> name -isLocallyDefinedName name = isLocalName name +isImplicitName :: Name -> Bool +-- An Implicit Name is one has a parent; that is, one whose definition +-- derives from the parent thing +isImplicitName name = isJust (nameParent_maybe name) --- 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 +nameModule name = nameModule_maybe name `orElse` pprPanic "nameModule" (ppr name) +nameModule_maybe (Name { n_sort = External mod _}) = Just mod +nameModule_maybe (Name { n_sort = WiredIn mod _ _ _}) = Just mod +nameModule_maybe name = Nothing -isUserExportedName (Name { n_sort = Exported }) = True -isUserExportedName other = False +nameIsLocalOrFrom from name + | isExternalName name = from == nameModule name + | otherwise = True + +isTyVarName :: Name -> Bool +isTyVarName name = isTvOcc (nameOccName name) isSystemName (Name {n_sort = System}) = True isSystemName other = False @@ -153,8 +189,8 @@ isSystemName other = False %************************************************************************ \begin{code} -mkLocalName :: Unique -> OccName -> SrcLoc -> Name -mkLocalName uniq occ loc = Name { n_uniq = uniq, n_sort = Local, n_occ = occ, n_loc = loc } +mkInternalName :: Unique -> OccName -> SrcLoc -> Name +mkInternalName uniq occ loc = Name { n_uniq = uniq, n_sort = Internal, n_occ = occ, n_loc = loc } -- NB: You might worry that after lots of huffing and -- puffing we might end up with two local names with distinct -- uniques, but the same OccName. Indeed we can, but that's ok @@ -164,71 +200,39 @@ mkLocalName uniq occ loc = Name { n_uniq = uniq, n_sort = Local, n_occ = occ, n_ -- * 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 - -- - -- Oct 00: now that Names lack Provenances, mkImportedLocalName doesn't make - -- sense any more, so it's just the same as mkLocalName -mkImportedLocalName uniq occ loc = mkLocalName uniq occ loc - - -mkGlobalName :: Unique -> Module -> OccName -> SrcLoc -> Name -mkGlobalName uniq mod occ loc = Name { n_uniq = uniq, n_sort = Global mod, - n_occ = occ, n_loc = loc } - - -mkKnownKeyGlobal :: RdrName -> Unique -> Name -mkKnownKeyGlobal rdr_name uniq - = mkGlobalName uniq (mkVanillaModule (rdrNameModule rdr_name)) - (rdrNameOcc rdr_name) - builtinSrcLoc - -mkWiredInName :: Module -> OccName -> Unique -> Name -mkWiredInName mod occ uniq = mkGlobalName uniq mod occ builtinSrcLoc - -mkSysLocalName :: Unique -> UserFS -> Name -mkSysLocalName uniq fs = Name { n_uniq = uniq, n_sort = System, - n_occ = mkVarOcc fs, n_loc = noSrcLoc } - -mkCCallName :: Unique -> EncodedString -> Name +mkExternalName :: Unique -> Module -> OccName -> Maybe Name -> SrcLoc -> Name +mkExternalName uniq mod occ mb_parent loc + = Name { n_uniq = uniq, n_sort = External mod mb_parent, + n_occ = occ, n_loc = loc } + +mkWiredInName :: Module -> OccName -> Unique + -> Maybe Name -> TyThing -> BuiltInSyntax -> Name +mkWiredInName mod occ uniq mb_parent thing built_in + = Name { n_uniq = uniq, + n_sort = WiredIn mod mb_parent thing built_in, + n_occ = occ, n_loc = wiredInSrcLoc } + +mkSystemName :: Unique -> OccName -> Name +mkSystemName uniq occ = Name { n_uniq = uniq, n_sort = System, + n_occ = occ, n_loc = noSrcLoc } + +mkSystemVarName :: Unique -> FastString -> Name +mkSystemVarName uniq fs = mkSystemName uniq (mkVarOccFS fs) + +mkSysTvName :: Unique -> FastString -> Name +mkSysTvName uniq fs = mkSystemName uniq (mkOccNameFS tvName fs) + +mkFCallName :: Unique -> String -> Name -- The encoded string completely describes the ccall -mkCCallName uniq str = Name { n_uniq = uniq, n_sort = Local, - n_occ = mkCCallOcc str, n_loc = noSrcLoc } - -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! - -- (Used only by the STG lambda lifter.) -mkTopName uniq mod fs - = Name { n_uniq = uniq, - n_sort = mk_top_sort mod, - n_occ = mkVarOcc (_PK_ ((_UNPK_ fs) ++ show uniq)), - n_loc = noSrcLoc } +mkFCallName uniq str = Name { n_uniq = uniq, n_sort = Internal, + n_occ = mkVarOcc str, n_loc = noSrcLoc } mkIPName :: Unique -> OccName -> Name mkIPName uniq occ = Name { n_uniq = uniq, - n_sort = Local, + n_sort = Internal, n_occ = occ, n_loc = noSrcLoc } - ---------------------------------------------------------------------- -mkDerivedName :: (OccName -> OccName) - -> Name -- Base name - -> Unique -- New unique - -> Name -- Result is always a value name - -mkDerivedName f name uniq = name {n_uniq = uniq, n_occ = f (n_occ name)} \end{code} \begin{code} @@ -237,84 +241,18 @@ mkDerivedName f name uniq = name {n_uniq = uniq, n_occ = f (n_occ name)} -- 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} - -setNameModuleAndLoc :: Name -> Module -> SrcLoc -> Name -setNameModuleAndLoc name mod loc = name {n_sort = set (n_sort name), n_loc = loc} - where - set (Global _) = Global mod - -setLocalNameSort :: Name -> Bool -> Name - -- Set the name's sort to Local or Exported, depending on the boolean -setLocalNameSort name is_exported = name { n_sort = if is_exported then Exported - else Local } -\end{code} - - -%************************************************************************ -%* * -\subsection{Tidying a name} -%* * -%************************************************************************ - -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} -tidyTopName :: Module -> TidyOccEnv -> Name -> (TidyOccEnv, Name) -tidyTopName mod env name - = (env', name') - where - (env', occ') = tidyOccName env (n_occ name) +tidyNameOcc :: Name -> OccName -> Name +-- We set the OccName of a Name when tidying +-- In doing so, we change System --> Internal, so that when we print +-- it we don't get the unique by default. It's tidy now! +tidyNameOcc name@(Name { n_sort = System }) occ = name { n_occ = occ, n_sort = Internal} +tidyNameOcc name occ = name { n_occ = occ } - name' = Name { n_uniq = n_uniq name, n_sort = mk_top_sort mod, - n_occ = occ', n_loc = n_loc name } - -mk_top_sort mod | all_toplev_ids_visible = Global mod - | otherwise = Local - -all_toplev_ids_visible = - not opt_OmitInterfacePragmas || -- Pragmas can make them visible - opt_EnsureSplittableC -- Splitting requires visiblilty +localiseName :: Name -> Name +localiseName n = n { n_sort = Internal } \end{code} - %************************************************************************ %* * \subsection{Predicates and selectors} @@ -323,32 +261,7 @@ all_toplev_ids_visible = \begin{code} hashName :: Name -> Int -hashName name = iBox (u2i (nameUnique name)) - - -nameRdrName :: Name -> RdrName --- Makes a qualified name for top-level (Global) names, whether locally defined or not --- and an unqualified name just for Locals -nameRdrName (Name { n_occ = occ, n_sort = Global mod }) = mkRdrQual (moduleName mod) occ -nameRdrName (Name { n_occ = occ }) = mkRdrUnqual 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) - -isDllName :: Name -> Bool - -- Does this name refer to something in a different DLL? -isDllName nm = not opt_Static && - not (isLocallyDefinedName nm) && -- isLocallyDefinedName test needed 'cos - not (isModuleInThisPackage (nameModule nm)) -- nameModule won't work on local names - - - -isTyVarName :: Name -> Bool -isTyVarName name = isTvOcc (nameOccName name) - +hashName name = getKey (nameUnique name) \end{code} @@ -384,79 +297,68 @@ instance NamedThing Name where %************************************************************************ %* * -\subsection{Name environment} -%* * -%************************************************************************ - -\begin{code} -type NameEnv a = UniqFM a -- Domain is Name - -emptyNameEnv :: NameEnv a -mkNameEnv :: [(Name,a)] -> NameEnv a -nameEnvElts :: NameEnv a -> [a] -extendNameEnv_C :: (a->a->a) -> NameEnv a -> Name -> a -> NameEnv a -extendNameEnv :: NameEnv a -> Name -> a -> NameEnv a -plusNameEnv :: NameEnv a -> NameEnv a -> NameEnv a -plusNameEnv_C :: (a->a->a) -> NameEnv a -> NameEnv a -> NameEnv a -extendNameEnvList:: NameEnv a -> [(Name,a)] -> NameEnv a -delFromNameEnv :: NameEnv a -> Name -> NameEnv a -elemNameEnv :: Name -> NameEnv a -> Bool -unitNameEnv :: Name -> a -> NameEnv a -lookupNameEnv :: NameEnv a -> Name -> Maybe a -lookupNameEnv_NF :: NameEnv a -> Name -> a -mapNameEnv :: (a->b) -> NameEnv a -> NameEnv b - -emptyNameEnv = emptyUFM -mkNameEnv = listToUFM -nameEnvElts = eltsUFM -extendNameEnv_C = addToUFM_C -extendNameEnv = addToUFM -plusNameEnv = plusUFM -plusNameEnv_C = plusUFM_C -extendNameEnvList= addListToUFM -delFromNameEnv = delFromUFM -elemNameEnv = elemUFM -mapNameEnv = mapUFM -unitNameEnv = unitUFM - -lookupNameEnv = lookupUFM -lookupNameEnv_NF env n = expectJust "lookupNameEnv_NF" (lookupUFM env n) -\end{code} - - -%************************************************************************ -%* * \subsection{Pretty printing} %* * %************************************************************************ \begin{code} instance Outputable Name where - -- When printing interfaces, all Locals have been given nice print-names ppr name = pprName name +instance OutputableBndr Name where + pprBndr _ name = pprName name + pprName (Name {n_sort = sort, n_uniq = uniq, n_occ = occ}) = getPprStyle $ \ sty -> - let local | debugStyle sty - = pprOccName occ <> text "{-" <> pprUnique uniq <> text "-}" - | codeStyle sty - = pprUnique uniq - | otherwise - = pprOccName occ - - global m | codeStyle sty - = ppr (moduleName m) <> char '_' <> pprOccName occ - | debugStyle sty || not (isLocalModule m) - = ppr (moduleName m) <> dot <> pprOccName occ - | otherwise - = pprOccName occ - in case sort of - System -> local - Local -> local - Exported -> local - Global mod -> global mod -\end{code} + case sort of + WiredIn mod _ _ builtin -> pprExternal sty uniq mod occ True builtin + External mod _ -> pprExternal sty uniq mod occ False UserSyntax + System -> pprSystem sty uniq occ + Internal -> pprInternal sty uniq occ + +pprExternal sty uniq mod occ is_wired is_builtin + | codeStyle sty = ppr_z_module mod <> char '_' <> ppr_z_occ_name occ + -- In code style, always qualify + -- ToDo: maybe we could print all wired-in things unqualified + -- in code style, to reduce symbol table bloat? + | debugStyle sty = ppr mod <> dot <> ppr_occ_name occ + <> braces (hsep [if is_wired then ptext SLIT("(w)") else empty, + pprNameSpaceBrief (occNameSpace occ), + pprUnique uniq]) + | BuiltInSyntax <- is_builtin = ppr_occ_name occ + -- never qualify builtin syntax + | unqualStyle sty mod occ = ppr_occ_name occ + | otherwise = ppr mod <> dot <> ppr_occ_name occ + +pprInternal sty uniq occ + | codeStyle sty = pprUnique uniq + | debugStyle sty = ppr_occ_name occ <> braces (hsep [pprNameSpaceBrief (occNameSpace occ), + pprUnique uniq]) + | dumpStyle sty = ppr_occ_name occ <> char '_' <> pprUnique uniq + -- For debug dumps, we're not necessarily dumping + -- tidied code, so we need to print the uniques. + | otherwise = ppr_occ_name occ -- User style + +-- Like Internal, except that we only omit the unique in Iface style +pprSystem sty uniq occ + | codeStyle sty = pprUnique uniq + | debugStyle sty = ppr_occ_name occ <> char '_' <> pprUnique uniq + <> braces (pprNameSpaceBrief (occNameSpace occ)) + | otherwise = ppr_occ_name occ <> char '_' <> pprUnique uniq + -- If the tidy phase hasn't run, the OccName + -- is unlikely to be informative (like 's'), + -- so print the unique + +ppr_occ_name occ = ftext (occNameFS occ) + -- Don't use pprOccName; instead, just print the string of the OccName; + -- we print the namespace in the debug stuff above + +-- In code style, we Z-encode the strings. The results of Z-encoding each FastString are +-- cached behind the scenes in the FastString implementation. +ppr_z_occ_name occ = ftext (zEncodeFS (occNameFS occ)) +ppr_z_module mod = ftext (zEncodeFS (moduleFS mod)) +\end{code} %************************************************************************ %* * @@ -474,16 +376,9 @@ class NamedThing a where \begin{code} getSrcLoc :: NamedThing a => a -> SrcLoc -isLocallyDefined :: NamedThing a => a -> Bool getOccString :: NamedThing a => a -> String -toRdrName :: NamedThing a => a -> RdrName getSrcLoc = nameSrcLoc . getName -isLocallyDefined = isLocallyDefinedName . getName -getOccString x = occNameString (getOccName x) -toRdrName = ifaceNameRdrName . getName +getOccString = occNameString . getOccName \end{code} -\begin{code} -{-# SPECIALIZE isLocallyDefined :: Name -> Bool #-} -\end{code}