[project @ 2005-06-15 12:03:19 by simonmar]
[ghc-hetmet.git] / ghc / compiler / basicTypes / Var.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
3 %
4 \section{@Vars@: Variables}
5
6 \begin{code}
7 module Var (
8         Var, 
9         varName, varUnique, 
10         setVarName, setVarUnique, setVarOcc,
11
12         -- TyVars
13         TyVar, mkTyVar, mkTcTyVar,
14         tyVarName, tyVarKind,
15         setTyVarName, setTyVarUnique,
16         tcTyVarDetails,
17
18         -- Ids
19         Id, DictId,
20         idName, idType, idUnique, idInfo, modifyIdInfo, maybeModifyIdInfo,
21         setIdName, setIdUnique, setIdType, setIdInfo, lazySetIdInfo, 
22         setIdExported, setIdNotExported, zapSpecPragmaId,
23
24         globalIdDetails, globaliseId, 
25
26         mkLocalId, mkExportedLocalId, mkSpecPragmaId,
27         mkGlobalId, 
28
29         isTyVar, isTcTyVar, isId, isLocalVar, isLocalId,
30         isGlobalId, isExportedId, isSpecPragmaId,
31         mustHaveLocalBinding
32     ) where
33
34 #include "HsVersions.h"
35
36 import {-# SOURCE #-}   TypeRep( Type )
37 import {-# SOURCE #-}   TcType( TcTyVarDetails )
38 import {-# SOURCE #-}   IdInfo( GlobalIdDetails, notGlobalId, IdInfo, seqIdInfo )
39
40 import Name             ( Name, OccName, NamedThing(..),
41                           setNameUnique, setNameOcc, nameUnique
42                         )
43 import Kind             ( Kind )
44 import Unique           ( Unique, Uniquable(..), mkUniqueGrimily, getKey# )
45 import FastTypes
46 import Outputable
47 \end{code}
48
49
50 %************************************************************************
51 %*                                                                      *
52 \subsection{The main data type declarations}
53 %*                                                                      *
54 %************************************************************************
55
56
57 Every @Var@ has a @Unique@, to uniquify it and for fast comparison, a
58 @Type@, and an @IdInfo@ (non-essential info about it, e.g.,
59 strictness).  The essential info about different kinds of @Vars@ is
60 in its @VarDetails@.
61
62 \begin{code}
63 data Var
64   = TyVar {
65         varName    :: !Name,
66         realUnique :: FastInt,          -- Key for fast comparison
67                                         -- Identical to the Unique in the name,
68                                         -- cached here for speed
69         tyVarKind :: Kind }
70
71   | TcTyVar {                           -- Used only during type inference
72         varName        :: !Name,
73         realUnique     :: FastInt,
74         tyVarKind      :: Kind,
75         tcTyVarDetails :: TcTyVarDetails }
76
77   | GlobalId {                  -- Used for imported Ids, dict selectors etc
78         varName    :: !Name,
79         realUnique :: FastInt,
80         idType     :: Type,
81         idInfo     :: IdInfo,
82         gblDetails :: GlobalIdDetails }
83
84   | LocalId {                   -- Used for locally-defined Ids (see NOTE below)
85         varName    :: !Name,
86         realUnique :: FastInt,
87         idType     :: Type,
88         idInfo     :: IdInfo,
89         lclDetails :: LocalIdDetails }
90
91 data LocalIdDetails 
92   = NotExported -- Not exported
93   | Exported    -- Exported
94   | SpecPragma  -- Not exported, but not to be discarded either
95                 -- It's unclean that this is so deeply built in
96   -- Exported and SpecPragma Ids are kept alive; 
97   -- NotExported things may be discarded as dead code.
98 \end{code}
99
100 LocalId and GlobalId
101 ~~~~~~~~~~~~~~~~~~~~
102 A GlobalId is
103   * always a constant (top-level)
104   * imported, or data constructor, or primop, or record selector
105   * has a Unique that is globally unique across the whole
106     GHC invocation (a single invocation may compile multiple modules)
107
108 A LocalId is 
109   * bound within an expression (lambda, case, local let(rec))
110   * or defined at top level in the module being compiled
111
112 After CoreTidy, top-level LocalIds are turned into GlobalIds
113  
114
115 \begin{code}
116 instance Outputable Var where
117   ppr var = ppr (varName var)
118
119 instance Show Var where
120   showsPrec p var = showsPrecSDoc p (ppr var)
121
122 instance NamedThing Var where
123   getName = varName
124
125 instance Uniquable Var where
126   getUnique = varUnique
127
128 instance Eq Var where
129     a == b = realUnique a ==# realUnique b
130
131 instance Ord Var where
132     a <= b = realUnique a <=# realUnique b
133     a <  b = realUnique a <#  realUnique b
134     a >= b = realUnique a >=# realUnique b
135     a >  b = realUnique a >#  realUnique b
136     a `compare` b = varUnique a `compare` varUnique b
137 \end{code}
138
139
140 \begin{code}
141 varUnique :: Var -> Unique
142 varUnique var = mkUniqueGrimily (iBox (realUnique var))
143
144 setVarUnique :: Var -> Unique -> Var
145 setVarUnique var uniq 
146   = var { realUnique = getKey# uniq, 
147           varName = setNameUnique (varName var) uniq }
148
149 setVarName :: Var -> Name -> Var
150 setVarName var new_name
151   = var { realUnique = getKey# (getUnique new_name), 
152           varName = new_name }
153
154 setVarOcc :: Var -> OccName -> Var
155 setVarOcc var new_occ
156   = var { varName = setNameOcc (varName var) new_occ }
157 \end{code}
158
159
160 %************************************************************************
161 %*                                                                      *
162 \subsection{Type variables}
163 %*                                                                      *
164 %************************************************************************
165
166 \begin{code}
167 type TyVar = Var
168
169 tyVarName = varName
170
171 setTyVarUnique = setVarUnique
172 setTyVarName   = setVarName
173 \end{code}
174
175 \begin{code}
176 mkTyVar :: Name -> Kind -> TyVar
177 mkTyVar name kind = TyVar { varName    = name
178                           , realUnique = getKey# (nameUnique name)
179                           , tyVarKind  = kind
180                         }
181
182 mkTcTyVar :: Name -> Kind -> TcTyVarDetails -> TyVar
183 mkTcTyVar name kind details
184   = TcTyVar {   varName    = name,
185                 realUnique = getKey# (nameUnique name),
186                 tyVarKind  = kind,
187                 tcTyVarDetails = details
188         }
189 \end{code}
190
191
192 %************************************************************************
193 %*                                                                      *
194 \subsection{Id Construction}
195 %*                                                                      *
196 %************************************************************************
197
198 Most Id-related functions are in Id.lhs and MkId.lhs
199
200 \begin{code}
201 type Id     = Var
202 type DictId = Id
203 \end{code}
204
205 \begin{code}
206 idName    = varName
207 idUnique  = varUnique
208
209 setIdUnique :: Id -> Unique -> Id
210 setIdUnique = setVarUnique
211
212 setIdName :: Id -> Name -> Id
213 setIdName = setVarName
214
215 setIdType :: Id -> Type -> Id
216 setIdType id ty = id {idType = ty}
217
218 setIdExported :: Id -> Id
219 -- Can be called on GlobalIds, such as data cons and class ops,
220 -- which are "born" as GlobalIds and automatically exported
221 setIdExported id@(LocalId {}) = id { lclDetails = Exported }
222 setIdExported other_id        = ASSERT( isId other_id ) other_id
223
224 setIdNotExported :: Id -> Id
225 -- We can only do this to LocalIds
226 setIdNotExported id = ASSERT( isLocalId id ) id { lclDetails = NotExported }
227
228 zapSpecPragmaId :: Id -> Id
229 zapSpecPragmaId id
230   | isSpecPragmaId id = id {lclDetails = NotExported}
231   | otherwise         = id
232
233 globaliseId :: GlobalIdDetails -> Id -> Id
234 -- If it's a local, make it global
235 globaliseId details id = GlobalId { varName    = varName id,
236                                     realUnique = realUnique id,
237                                     idType     = idType id,
238                                     idInfo     = idInfo id,
239                                     gblDetails = details }
240
241 lazySetIdInfo :: Id -> IdInfo -> Id
242 lazySetIdInfo id info = id {idInfo = info}
243
244 setIdInfo :: Id -> IdInfo -> Id
245 setIdInfo id info = seqIdInfo info `seq` id {idInfo = info}
246         -- Try to avoid spack leaks by seq'ing
247
248 modifyIdInfo :: (IdInfo -> IdInfo) -> Id -> Id
249 modifyIdInfo fn id
250   = seqIdInfo new_info `seq` id {idInfo = new_info}
251   where
252     new_info = fn (idInfo id)
253
254 -- maybeModifyIdInfo tries to avoid unnecesary thrashing
255 maybeModifyIdInfo :: (IdInfo -> Maybe IdInfo) -> Id -> Id
256 maybeModifyIdInfo fn id
257   = case fn (idInfo id) of
258         Nothing       -> id
259         Just new_info -> id {idInfo = new_info}
260 \end{code}
261
262 %************************************************************************
263 %*                                                                      *
264 \subsection{Predicates over variables
265 %*                                                                      *
266 %************************************************************************
267
268 \begin{code}
269 mkGlobalId :: GlobalIdDetails -> Name -> Type -> IdInfo -> Id
270 mkGlobalId details name ty info 
271   = GlobalId {  varName    = name, 
272                 realUnique = getKey# (nameUnique name),         -- Cache the unique
273                 idType     = ty,        
274                 gblDetails = details,
275                 idInfo     = info }
276
277 mk_local_id :: Name -> Type -> LocalIdDetails -> IdInfo -> Id
278 mk_local_id name ty details info
279   = LocalId {   varName    = name, 
280                 realUnique = getKey# (nameUnique name),         -- Cache the unique
281                 idType     = ty,        
282                 lclDetails = details,
283                 idInfo     = info }
284
285 mkLocalId :: Name -> Type -> IdInfo -> Id
286 mkLocalId name ty info = mk_local_id name ty NotExported info
287
288 mkExportedLocalId :: Name -> Type -> IdInfo -> Id
289 mkExportedLocalId name ty info = mk_local_id name ty Exported info
290
291 mkSpecPragmaId :: Name -> Type -> IdInfo -> Id
292 mkSpecPragmaId name ty info = mk_local_id name ty SpecPragma info
293 \end{code}
294
295 \begin{code}
296 isTyVar, isTcTyVar                       :: Var -> Bool
297 isId, isLocalVar, isLocalId              :: Var -> Bool
298 isGlobalId, isExportedId, isSpecPragmaId :: Var -> Bool
299 mustHaveLocalBinding                     :: Var -> Bool
300
301 isTyVar (TyVar {})   = True
302 isTyVar (TcTyVar {}) = True
303 isTyVar other        = False
304
305 isTcTyVar (TcTyVar {}) = True
306 isTcTyVar other        = False
307
308 isId (LocalId {})  = True
309 isId (GlobalId {}) = True
310 isId other         = False
311
312 isLocalId (LocalId {}) = True
313 isLocalId other        = False
314
315 -- isLocalVar returns True for type variables as well as local Ids
316 -- These are the variables that we need to pay attention to when finding free
317 -- variables, or doing dependency analysis.
318 isLocalVar (GlobalId {}) = False 
319 isLocalVar other         = True
320
321 -- mustHaveLocalBinding returns True of Ids and TyVars
322 -- that must have a binding in this module.  The converse
323 -- is not quite right: there are some GlobalIds that must have
324 -- bindings, such as record selectors.  But that doesn't matter,
325 -- because it's only used for assertions
326 mustHaveLocalBinding var = isLocalVar var
327
328 isGlobalId (GlobalId {}) = True
329 isGlobalId other         = False
330
331 -- isExportedId means "don't throw this away"
332 isExportedId (GlobalId {}) = True
333 isExportedId (LocalId {lclDetails = details}) 
334   = case details of
335         Exported   -> True
336         SpecPragma -> True
337         other      -> False
338 isExportedId other = False
339
340 isSpecPragmaId (LocalId {lclDetails = SpecPragma}) = True
341 isSpecPragmaId other = False
342 \end{code}
343
344 \begin{code}
345 globalIdDetails :: Var -> GlobalIdDetails
346 -- Works OK on local Ids too, returning notGlobalId
347 globalIdDetails (GlobalId {gblDetails = details}) = details
348 globalIdDetails other                             = notGlobalId
349 \end{code}
350