[project @ 1999-03-02 19:01:56 by sof]
[ghc-hetmet.git] / ghc / compiler / basicTypes / Module.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
3 %
4 \section[Module]{The @Module@ module.}
5
6 Representing modules and their flavours.
7
8 \begin{code}
9 module Module 
10     (
11       Module                -- abstract, instance of Eq, Ord, Outputable
12     , moduleString          -- :: Module -> EncodedString
13     , moduleUserString      -- :: Module -> UserString
14     , moduleIfaceFlavour    -- :: Module -> IfaceFlavour
15     , moduleFS              -- :: Module -> EncodedFS
16
17     , mkBootModule          -- :: Module -> Module
18     , setModuleFlavour      -- :: IfaceFlavour -> Module -> Module
19
20     , mkDynamicModule       -- :: Module -> Module
21     , isDynamicModule       -- :: Module -> Bool
22
23     , mkSrcModule
24     , mkPrelModule          -- :: UserString -> Module
25
26     , mkSrcModuleFS         -- :: UserFS -> Module
27     , mkSysModuleFS         -- :: EncodedFS -> IfaceFlavour -> Module
28     , mkImportModuleFS      -- :: UserFS -> IfaceFlavour -> Module
29
30     , pprModule
31     , pprModuleSep
32     , pprModuleBoot
33  
34       -- IfaceFlavour
35     , IfaceFlavour
36     , hiFile
37     , hiBootFile            -- :: IfaceFlavour
38     , mkDynFlavour          -- :: Bool -> IfaceFlavour -> IfaceFlavour
39
40     , bootFlavour           -- :: IfaceFlavour -> Bool
41
42     ) where
43
44 #include "HsVersions.h"
45 import OccName
46 import Outputable
47 import CmdLineOpts ( opt_Static )
48
49 \end{code}
50
51
52 %************************************************************************
53 %*                                                                      *
54 \subsection{Interface file flavour}
55 %*                                                                      *
56 %************************************************************************
57
58 The IfaceFlavour type is used mainly in an imported Name's Provenance
59 to say whether the name comes from a regular .hi file, or whether it comes
60 from a hand-written .hi-boot file.  This is important, because it has to be 
61 propagated.  Suppose
62
63         C.hs imports B
64         B.hs imports A
65         A.hs imports C {-# SOURCE -#} ( f )
66
67 Then in A.hi we may mention C.f, in an inlining.  When compiling B we *must not* 
68 read C.f's details from C.hi, even if the latter happens to exist from an earlier
69 compilation run.  So we use the name "C!f" in A.hi, and when looking for an interface
70 file with details of C!f we look in C.hi-boot.  The "!" stuff is recorded in the
71 IfaceFlavour in the Module of C.f in A. 
72
73 Not particularly beautiful, but it works.
74
75 A further twist to the tale is the support for dynamically linked libraries under
76 Win32. Here, dealing with the use of global variables that's residing in a DLL
77 requires special handling at the point of use (there's an extra level of indirection,
78 i.e., (**v) to get at v's value, rather than just (*v) .) When slurping in an
79 interface file we then record whether it's coming from a .hi corresponding to a
80 module that's packaged up in a DLL or not, so that we later can emit the
81 appropriate code.
82
83 The logic for how an interface file is marked as corresponding to a module that's
84 hiding in a DLL is explained elsewhere (ToDo: give renamer href here.)
85
86 \begin{code}
87 data IfaceFlavour = HiFile              -- The thing comes from a standard interface file
88                                         -- or from the source file itself
89                   | HiBootFile          -- ... or from a handwritten "hi-boot" interface file
90
91                   | HiDllFile           -- The thing comes from a standard interface file, but
92                                         -- it's corresponding object code is residing in a DLL.
93                                         -- (see above.)
94                   deriving( Eq )
95
96 hiFile     = HiFile
97 hiDllFile  = HiDllFile
98 hiBootFile = HiBootFile
99
100 -- badly named, isn't clear whether the boolean deals with
101 -- the 'bootedness' or the 'DLLedness'. ToDo: improve.
102 mkDynFlavour :: Bool{-is really dyn?-} -> IfaceFlavour -> IfaceFlavour
103 mkDynFlavour True HiFile = HiDllFile
104 mkDynFlavour _    x      = x
105
106 instance Text IfaceFlavour where        -- Just used in debug prints of lex tokens
107   showsPrec n HiBootFile s = "!" ++ s
108   showsPrec n HiFile     s = s
109   showsPrec n HiDllFile  s = s
110
111 bootFlavour :: IfaceFlavour -> Bool
112 bootFlavour HiBootFile = True
113 bootFlavour HiFile     = False
114 bootFlavour HiDllFile  = False
115 \end{code}
116
117
118 %************************************************************************
119 %*                                                                      *
120 \subsection[Module]{The name of a module}
121 %*                                                                      *
122 %************************************************************************
123
124 \begin{code}
125 data Module = Module
126                 EncodedFS
127                 IfaceFlavour
128         -- Haskell module names can include the quote character ',
129         -- so the module names have the z-encoding applied to them
130 \end{code}
131
132 \begin{code}
133 instance Outputable Module where
134   ppr = pprModule
135
136 -- Ignore the IfaceFlavour when comparing modules
137 instance Eq Module where
138   (Module m1 _) == (Module m2 _) = m1 == m2
139
140 instance Ord Module where
141   (Module m1 _) `compare` (Module m2 _) = m1 `compare` m2
142 \end{code}
143
144
145 \begin{code}
146 pprModule :: Module -> SDoc
147 pprModule (Module mod _) = pprEncodedFS mod
148
149 pprModuleSep, pprModuleBoot :: Module -> SDoc
150 pprModuleSep (Module mod HiFile)     = dot
151 pprModuleSep (Module mod HiDllFile)  = dot
152 pprModuleSep (Module mod HiBootFile) = char '!'
153
154 pprModuleBoot (Module mod HiFile)     = empty
155 pprModuleBoot (Module mod HiDllFile)  = empty
156 pprModuleBoot (Module mod HiBootFile) = char '!'
157 \end{code}
158
159
160 \begin{code}
161 mkSrcModule :: UserString -> Module
162 mkSrcModule s = Module (_PK_ (encode s)) HiFile
163
164 mkPrelModule :: UserString -> Module
165 mkPrelModule s = Module (_PK_ (encode s)) ilk
166  where 
167   ilk
168    | opt_Static = HiFile
169    | otherwise  = HiDllFile
170
171 mkSrcModuleFS :: UserFS -> Module
172 mkSrcModuleFS s = Module (encodeFS s) HiFile
173
174 mkImportModuleFS :: UserFS -> IfaceFlavour -> Module
175 mkImportModuleFS s hif = Module (encodeFS s) hif
176
177 mkSysModuleFS :: EncodedFS -> IfaceFlavour -> Module
178 mkSysModuleFS s hif = Module s hif
179
180 mkBootModule :: Module -> Module
181 mkBootModule (Module s _) = Module s HiBootFile
182
183 mkDynamicModule :: Module -> Module
184 mkDynamicModule (Module s HiFile) = Module s HiDllFile
185 mkDynamicModule m = m
186
187 setModuleFlavour :: IfaceFlavour -> Module -> Module
188 setModuleFlavour hif (Module n _) = Module n hif
189
190 moduleString :: Module -> EncodedString
191 moduleString (Module mod _) = _UNPK_ mod
192
193 moduleFS :: Module -> EncodedFS
194 moduleFS (Module mod _) = mod
195
196 moduleUserString :: Module -> UserString
197 moduleUserString (Module mod _) = decode (_UNPK_ mod)
198
199 moduleIfaceFlavour :: Module -> IfaceFlavour
200 moduleIfaceFlavour (Module _ hif) = hif
201 \end{code}
202
203 \begin{code}
204 isDynamicModule :: Module -> Bool
205 isDynamicModule (Module _ HiDllFile)  = True
206 isDynamicModule _                     = False
207 \end{code}