2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 \section[Module]{The @Module@ module.}
6 Representing modules and their flavours.
11 Module -- abstract, instance of Eq, Ord, Outputable
12 , moduleString -- :: Module -> EncodedString
13 , moduleUserString -- :: Module -> UserString
14 , moduleIfaceFlavour -- :: Module -> IfaceFlavour
15 , moduleFS -- :: Module -> EncodedFS
17 , mkBootModule -- :: Module -> Module
18 , setModuleFlavour -- :: IfaceFlavour -> Module -> Module
20 , mkDynamicModule -- :: Module -> Module
21 , isDynamicModule -- :: Module -> Bool
24 , mkPrelModule -- :: UserString -> Module
26 , mkSrcModuleFS -- :: UserFS -> Module
27 , mkSysModuleFS -- :: EncodedFS -> IfaceFlavour -> Module
28 , mkImportModuleFS -- :: UserFS -> IfaceFlavour -> Module
37 , hiBootFile -- :: IfaceFlavour
38 , mkDynFlavour -- :: Bool -> IfaceFlavour -> IfaceFlavour
40 , bootFlavour -- :: IfaceFlavour -> Bool
44 #include "HsVersions.h"
47 import CmdLineOpts ( opt_Static )
52 %************************************************************************
54 \subsection{Interface file flavour}
56 %************************************************************************
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
65 A.hs imports C {-# SOURCE -#} ( f )
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.
73 Not particularly beautiful, but it works.
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
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.)
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
91 | HiDllFile -- The thing comes from a standard interface file, but
92 -- it's corresponding object code is residing in a DLL.
98 hiBootFile = HiBootFile
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
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
111 bootFlavour :: IfaceFlavour -> Bool
112 bootFlavour HiBootFile = True
113 bootFlavour HiFile = False
114 bootFlavour HiDllFile = False
118 %************************************************************************
120 \subsection[Module]{The name of a module}
122 %************************************************************************
128 -- Haskell module names can include the quote character ',
129 -- so the module names have the z-encoding applied to them
133 instance Outputable Module where
136 -- Ignore the IfaceFlavour when comparing modules
137 instance Eq Module where
138 (Module m1 _) == (Module m2 _) = m1 == m2
140 instance Ord Module where
141 (Module m1 _) `compare` (Module m2 _) = m1 `compare` m2
146 pprModule :: Module -> SDoc
147 pprModule (Module mod _) = pprEncodedFS mod
149 pprModuleSep, pprModuleBoot :: Module -> SDoc
150 pprModuleSep (Module mod HiFile) = dot
151 pprModuleSep (Module mod HiDllFile) = dot
152 pprModuleSep (Module mod HiBootFile) = char '!'
154 pprModuleBoot (Module mod HiFile) = empty
155 pprModuleBoot (Module mod HiDllFile) = empty
156 pprModuleBoot (Module mod HiBootFile) = char '!'
161 mkSrcModule :: UserString -> Module
162 mkSrcModule s = Module (_PK_ (encode s)) HiFile
164 mkPrelModule :: UserString -> Module
165 mkPrelModule s = Module (_PK_ (encode s)) ilk
168 | opt_Static = HiFile
169 | otherwise = HiDllFile
171 mkSrcModuleFS :: UserFS -> Module
172 mkSrcModuleFS s = Module (encodeFS s) HiFile
174 mkImportModuleFS :: UserFS -> IfaceFlavour -> Module
175 mkImportModuleFS s hif = Module (encodeFS s) hif
177 mkSysModuleFS :: EncodedFS -> IfaceFlavour -> Module
178 mkSysModuleFS s hif = Module s hif
180 mkBootModule :: Module -> Module
181 mkBootModule (Module s _) = Module s HiBootFile
183 mkDynamicModule :: Module -> Module
184 mkDynamicModule (Module s HiFile) = Module s HiDllFile
185 mkDynamicModule m = m
187 setModuleFlavour :: IfaceFlavour -> Module -> Module
188 setModuleFlavour hif (Module n _) = Module n hif
190 moduleString :: Module -> EncodedString
191 moduleString (Module mod _) = _UNPK_ mod
193 moduleFS :: Module -> EncodedFS
194 moduleFS (Module mod _) = mod
196 moduleUserString :: Module -> UserString
197 moduleUserString (Module mod _) = decode (_UNPK_ mod)
199 moduleIfaceFlavour :: Module -> IfaceFlavour
200 moduleIfaceFlavour (Module _ hif) = hif
204 isDynamicModule :: Module -> Bool
205 isDynamicModule (Module _ HiDllFile) = True
206 isDynamicModule _ = False