PageRenderTime 27ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/ghc-7.0.4/compiler/iface/IfaceEnv.lhs

http://picorec.googlecode.com/
Haskell | 348 lines | 249 code | 51 blank | 48 comment | 6 complexity | 923bf8873d2eed96bff4aa52bb2ec69e MD5 | raw file
Possible License(s): BSD-3-Clause, BSD-2-Clause
  1. (c) The University of Glasgow 2002-2006
  2. \begin{code}
  3. module IfaceEnv (
  4. newGlobalBinder, newIPName, newImplicitBinder,
  5. lookupIfaceTop,
  6. lookupOrig, lookupOrigNameCache, extendNameCache,
  7. newIfaceName, newIfaceNames,
  8. extendIfaceIdEnv, extendIfaceTyVarEnv,
  9. tcIfaceLclId, tcIfaceTyVar, lookupIfaceTyVar,
  10. tcIfaceTick,
  11. ifaceExportNames,
  12. -- Name-cache stuff
  13. allocateGlobalBinder, initNameCache,
  14. getNameCache, mkNameCacheUpdater, NameCacheUpdater
  15. ) where
  16. #include "HsVersions.h"
  17. import TcRnMonad
  18. import TysWiredIn
  19. import HscTypes
  20. import TyCon
  21. import DataCon
  22. import Var
  23. import Name
  24. import PrelNames
  25. import Module
  26. import UniqFM
  27. import FastString
  28. import UniqSupply
  29. import BasicTypes
  30. import SrcLoc
  31. import MkId
  32. import Outputable
  33. import Exception ( evaluate )
  34. import Data.IORef ( atomicModifyIORef, readIORef )
  35. import qualified Data.Map as Map
  36. \end{code}
  37. %*********************************************************
  38. %* *
  39. Allocating new Names in the Name Cache
  40. %* *
  41. %*********************************************************
  42. \begin{code}
  43. newGlobalBinder :: Module -> OccName -> SrcSpan -> TcRnIf a b Name
  44. -- Used for source code and interface files, to make the
  45. -- Name for a thing, given its Module and OccName
  46. --
  47. -- The cache may already already have a binding for this thing,
  48. -- because we may have seen an occurrence before, but now is the
  49. -- moment when we know its Module and SrcLoc in their full glory
  50. newGlobalBinder mod occ loc
  51. = do mod `seq` occ `seq` return () -- See notes with lookupOrig
  52. -- traceIf (text "newGlobalBinder" <+> ppr mod <+> ppr occ <+> ppr loc)
  53. updNameCache $ \name_cache ->
  54. allocateGlobalBinder name_cache mod occ loc
  55. allocateGlobalBinder
  56. :: NameCache
  57. -> Module -> OccName -> SrcSpan
  58. -> (NameCache, Name)
  59. allocateGlobalBinder name_supply mod occ loc
  60. = case lookupOrigNameCache (nsNames name_supply) mod occ of
  61. -- A hit in the cache! We are at the binding site of the name.
  62. -- This is the moment when we know the SrcLoc
  63. -- of the Name, so we set this field in the Name we return.
  64. --
  65. -- Then (bogus) multiple bindings of the same Name
  66. -- get different SrcLocs can can be reported as such.
  67. --
  68. -- Possible other reason: it might be in the cache because we
  69. -- encountered an occurrence before the binding site for an
  70. -- implicitly-imported Name. Perhaps the current SrcLoc is
  71. -- better... but not really: it'll still just say 'imported'
  72. --
  73. -- IMPORTANT: Don't mess with wired-in names.
  74. -- Their wired-in-ness is in their NameSort
  75. -- and their Module is correct.
  76. Just name | isWiredInName name -> (name_supply, name)
  77. | otherwise -> (new_name_supply, name')
  78. where
  79. uniq = nameUnique name
  80. name' = mkExternalName uniq mod occ loc
  81. new_cache = extendNameCache (nsNames name_supply) mod occ name'
  82. new_name_supply = name_supply {nsNames = new_cache}
  83. -- Miss in the cache!
  84. -- Build a completely new Name, and put it in the cache
  85. Nothing -> (new_name_supply, name)
  86. where
  87. (us', us1) = splitUniqSupply (nsUniqs name_supply)
  88. uniq = uniqFromSupply us1
  89. name = mkExternalName uniq mod occ loc
  90. new_cache = extendNameCache (nsNames name_supply) mod occ name
  91. new_name_supply = name_supply {nsUniqs = us', nsNames = new_cache}
  92. newImplicitBinder :: Name -- Base name
  93. -> (OccName -> OccName) -- Occurrence name modifier
  94. -> TcRnIf m n Name -- Implicit name
  95. -- Called in BuildTyCl to allocate the implicit binders of type/class decls
  96. -- For source type/class decls, this is the first occurrence
  97. -- For iface ones, the LoadIface has alrady allocated a suitable name in the cache
  98. newImplicitBinder base_name mk_sys_occ
  99. | Just mod <- nameModule_maybe base_name
  100. = newGlobalBinder mod occ loc
  101. | otherwise -- When typechecking a [d| decl bracket |],
  102. -- TH generates types, classes etc with Internal names,
  103. -- so we follow suit for the implicit binders
  104. = do { uniq <- newUnique
  105. ; return (mkInternalName uniq occ loc) }
  106. where
  107. occ = mk_sys_occ (nameOccName base_name)
  108. loc = nameSrcSpan base_name
  109. ifaceExportNames :: [IfaceExport] -> TcRnIf gbl lcl [AvailInfo]
  110. ifaceExportNames exports = do
  111. mod_avails <- mapM (\(mod,avails) -> mapM (lookupAvail mod) avails) exports
  112. return (concat mod_avails)
  113. -- Convert OccNames in GenAvailInfo to Names.
  114. lookupAvail :: Module -> GenAvailInfo OccName -> TcRnIf a b AvailInfo
  115. lookupAvail mod (Avail n) = do
  116. n' <- lookupOrig mod n
  117. return (Avail n')
  118. lookupAvail mod (AvailTC p_occ occs) = do
  119. p_name <- lookupOrig mod p_occ
  120. let lookup_sub occ | occ == p_occ = return p_name
  121. | otherwise = lookupOrig mod occ
  122. subs <- mapM lookup_sub occs
  123. return (AvailTC p_name subs)
  124. -- Remember that 'occs' is all the exported things, including
  125. -- the parent. It's possible to export just class ops without
  126. -- the class, which shows up as C( op ) here. If the class was
  127. -- exported too we'd have C( C, op )
  128. lookupOrig :: Module -> OccName -> TcRnIf a b Name
  129. lookupOrig mod occ
  130. = do { -- First ensure that mod and occ are evaluated
  131. -- If not, chaos can ensue:
  132. -- we read the name-cache
  133. -- then pull on mod (say)
  134. -- which does some stuff that modifies the name cache
  135. -- This did happen, with tycon_mod in TcIface.tcIfaceAlt (DataAlt..)
  136. mod `seq` occ `seq` return ()
  137. -- ; traceIf (text "lookup_orig" <+> ppr mod <+> ppr occ)
  138. ; updNameCache $ \name_cache ->
  139. case lookupOrigNameCache (nsNames name_cache) mod occ of {
  140. Just name -> (name_cache, name);
  141. Nothing ->
  142. let
  143. us = nsUniqs name_cache
  144. uniq = uniqFromSupply us
  145. name = mkExternalName uniq mod occ noSrcSpan
  146. new_cache = extendNameCache (nsNames name_cache) mod occ name
  147. in
  148. case splitUniqSupply us of { (us',_) -> do
  149. (name_cache{ nsUniqs = us', nsNames = new_cache }, name)
  150. }}}
  151. newIPName :: IPName OccName -> TcRnIf m n (IPName Name)
  152. newIPName occ_name_ip =
  153. updNameCache $ \name_cache ->
  154. let
  155. ipcache = nsIPs name_cache
  156. key = occ_name_ip -- Ensures that ?x and %x get distinct Names
  157. in
  158. case Map.lookup key ipcache of
  159. Just name_ip -> (name_cache, name_ip)
  160. Nothing -> (new_ns, name_ip)
  161. where
  162. (us', us1) = splitUniqSupply (nsUniqs name_cache)
  163. uniq = uniqFromSupply us1
  164. name_ip = mapIPName (mkIPName uniq) occ_name_ip
  165. new_ipcache = Map.insert key name_ip ipcache
  166. new_ns = name_cache {nsUniqs = us', nsIPs = new_ipcache}
  167. \end{code}
  168. %************************************************************************
  169. %* *
  170. Name cache access
  171. %* *
  172. %************************************************************************
  173. \begin{code}
  174. lookupOrigNameCache :: OrigNameCache -> Module -> OccName -> Maybe Name
  175. lookupOrigNameCache _ mod occ
  176. -- XXX Why is gHC_UNIT not mentioned here?
  177. | mod == gHC_TUPLE || mod == gHC_PRIM, -- Boxed tuples from one,
  178. Just tup_info <- isTupleOcc_maybe occ -- unboxed from the other
  179. = -- Special case for tuples; there are too many
  180. -- of them to pre-populate the original-name cache
  181. Just (mk_tup_name tup_info)
  182. where
  183. mk_tup_name (ns, boxity, arity)
  184. | ns == tcName = tyConName (tupleTyCon boxity arity)
  185. | ns == dataName = dataConName (tupleCon boxity arity)
  186. | otherwise = Var.varName (dataConWorkId (tupleCon boxity arity))
  187. lookupOrigNameCache nc mod occ -- The normal case
  188. = case lookupModuleEnv nc mod of
  189. Nothing -> Nothing
  190. Just occ_env -> lookupOccEnv occ_env occ
  191. extendOrigNameCache :: OrigNameCache -> Name -> OrigNameCache
  192. extendOrigNameCache nc name
  193. = ASSERT2( isExternalName name, ppr name )
  194. extendNameCache nc (nameModule name) (nameOccName name) name
  195. extendNameCache :: OrigNameCache -> Module -> OccName -> Name -> OrigNameCache
  196. extendNameCache nc mod occ name
  197. = extendModuleEnvWith combine nc mod (unitOccEnv occ name)
  198. where
  199. combine _ occ_env = extendOccEnv occ_env occ name
  200. getNameCache :: TcRnIf a b NameCache
  201. getNameCache = do { HscEnv { hsc_NC = nc_var } <- getTopEnv;
  202. readMutVar nc_var }
  203. updNameCache :: (NameCache -> (NameCache, c)) -> TcRnIf a b c
  204. updNameCache upd_fn = do
  205. HscEnv { hsc_NC = nc_var } <- getTopEnv
  206. atomicUpdMutVar' nc_var upd_fn
  207. -- | A function that atomically updates the name cache given a modifier
  208. -- function. The second result of the modifier function will be the result
  209. -- of the IO action.
  210. type NameCacheUpdater c = (NameCache -> (NameCache, c)) -> IO c
  211. -- | Return a function to atomically update the name cache.
  212. mkNameCacheUpdater :: TcRnIf a b (NameCacheUpdater c)
  213. mkNameCacheUpdater = do
  214. nc_var <- hsc_NC `fmap` getTopEnv
  215. let update_nc f = do r <- atomicModifyIORef nc_var f
  216. _ <- evaluate =<< readIORef nc_var
  217. return r
  218. return update_nc
  219. \end{code}
  220. \begin{code}
  221. initNameCache :: UniqSupply -> [Name] -> NameCache
  222. initNameCache us names
  223. = NameCache { nsUniqs = us,
  224. nsNames = initOrigNames names,
  225. nsIPs = Map.empty }
  226. initOrigNames :: [Name] -> OrigNameCache
  227. initOrigNames names = foldl extendOrigNameCache emptyModuleEnv names
  228. \end{code}
  229. %************************************************************************
  230. %* *
  231. Type variables and local Ids
  232. %* *
  233. %************************************************************************
  234. \begin{code}
  235. tcIfaceLclId :: FastString -> IfL Id
  236. tcIfaceLclId occ
  237. = do { lcl <- getLclEnv
  238. ; case (lookupUFM (if_id_env lcl) occ) of
  239. Just ty_var -> return ty_var
  240. Nothing -> failIfM (text "Iface id out of scope: " <+> ppr occ)
  241. }
  242. extendIfaceIdEnv :: [Id] -> IfL a -> IfL a
  243. extendIfaceIdEnv ids thing_inside
  244. = do { env <- getLclEnv
  245. ; let { id_env' = addListToUFM (if_id_env env) pairs
  246. ; pairs = [(occNameFS (getOccName id), id) | id <- ids] }
  247. ; setLclEnv (env { if_id_env = id_env' }) thing_inside }
  248. tcIfaceTyVar :: FastString -> IfL TyVar
  249. tcIfaceTyVar occ
  250. = do { lcl <- getLclEnv
  251. ; case (lookupUFM (if_tv_env lcl) occ) of
  252. Just ty_var -> return ty_var
  253. Nothing -> failIfM (text "Iface type variable out of scope: " <+> ppr occ)
  254. }
  255. lookupIfaceTyVar :: FastString -> IfL (Maybe TyVar)
  256. lookupIfaceTyVar occ
  257. = do { lcl <- getLclEnv
  258. ; return (lookupUFM (if_tv_env lcl) occ) }
  259. extendIfaceTyVarEnv :: [TyVar] -> IfL a -> IfL a
  260. extendIfaceTyVarEnv tyvars thing_inside
  261. = do { env <- getLclEnv
  262. ; let { tv_env' = addListToUFM (if_tv_env env) pairs
  263. ; pairs = [(occNameFS (getOccName tv), tv) | tv <- tyvars] }
  264. ; setLclEnv (env { if_tv_env = tv_env' }) thing_inside }
  265. \end{code}
  266. %************************************************************************
  267. %* *
  268. Getting from RdrNames to Names
  269. %* *
  270. %************************************************************************
  271. \begin{code}
  272. lookupIfaceTop :: OccName -> IfL Name
  273. -- Look up a top-level name from the current Iface module
  274. lookupIfaceTop occ
  275. = do { env <- getLclEnv; lookupOrig (if_mod env) occ }
  276. newIfaceName :: OccName -> IfL Name
  277. newIfaceName occ
  278. = do { uniq <- newUnique
  279. ; return $! mkInternalName uniq occ noSrcSpan }
  280. newIfaceNames :: [OccName] -> IfL [Name]
  281. newIfaceNames occs
  282. = do { uniqs <- newUniqueSupply
  283. ; return [ mkInternalName uniq occ noSrcSpan
  284. | (occ,uniq) <- occs `zip` uniqsFromSupply uniqs] }
  285. \end{code}
  286. %************************************************************************
  287. %* *
  288. (Re)creating tick boxes
  289. %* *
  290. %************************************************************************
  291. \begin{code}
  292. tcIfaceTick :: Module -> Int -> IfL Id
  293. tcIfaceTick modName tickNo
  294. = do { uniq <- newUnique
  295. ; return $ mkTickBoxOpId uniq modName tickNo
  296. }
  297. \end{code}