[project @ 1998-02-25 19:48:54 by sof]
authorsof <unknown>
Wed, 25 Feb 1998 19:49:13 +0000 (19:49 +0000)
committersof <unknown>
Wed, 25 Feb 1998 19:49:13 +0000 (19:49 +0000)
Interface file version checking support. Added a compiler version field
to the interface file header. The format is now

  _interface_ <IfaceName> <ModuleVersion> <CompilerVersion>

where the compiler version follow the value of $(ProjectVersionInt).
Any mismatch in version numbers causes the renamer to give up.

A compiler version number of 0 means turn off version checking (used
by PrelGHC.hi to avoid having to update every time we release.)

.hi-boot files are treated specially, the absence of a compiler
version number in the header is taken to mean that there was a `0'.
Need to do this since hsc's .hi-boot files have to also be useable
by versions of the compiler that don't grok version info in interface
files (e.g., ghc-2.10.)

ghc/compiler/Makefile
ghc/compiler/basicTypes/SrcLoc.lhs
ghc/compiler/main/MkIface.lhs
ghc/compiler/reader/Lex.lhs
ghc/compiler/rename/ParseIface.y
ghc/compiler/rename/Rename.lhs
ghc/driver/ghc-iface.lprl
ghc/lib/std/PrelGHC.hi-boot

index a603512..ad5d6da 100644 (file)
@@ -1,5 +1,5 @@
 # -----------------------------------------------------------------------------
-# $Id: Makefile,v 1.33 1998/01/12 14:44:37 simonm Exp $
+# $Id: Makefile,v 1.34 1998/02/25 19:48:54 sof Exp $
 
 TOP = ..
 include $(TOP)/mk/boilerplate.mk
@@ -147,6 +147,7 @@ coreSyn/AnnCoreSyn_HC_OPTS  = -fno-omit-reexported-instances
 hsSyn/HsExpr_HC_OPTS           = -K2m
 hsSyn/HsSyn_HC_OPTS            = -fno-omit-reexported-instances
 main/Main_HC_OPTS              = -fvia-C -DPROJECTVERSION=$(GhcProjectVersion)
+main/MkIface_HC_OPTS            = -DPROJECTVERSION=$(GhcProjectVersionInt)
 main/CmdLineOpts_HC_OPTS       = -fvia-C
 nativeGen/PprMach_HC_OPTS      = -K2m
 nativeGen/MachMisc_HC_OPTS     = -K2m -fvia-C
@@ -165,7 +166,7 @@ parser/U_qid_HC_OPTS                = -fvia-C '-\#include"hspincl.h"'
 parser/U_tree_HC_OPTS          = -H12m -fvia-C '-\#include"hspincl.h"'
 parser/U_ttype_HC_OPTS                 = -fvia-C '-\#include"hspincl.h"'
 prelude/PrimOp_HC_OPTS                 = -H12m -K3m
-reader/Lex_HC_OPTS             = -K2m -H16m -fvia-C
+reader/Lex_HC_OPTS             = -K2m -H16m -fvia-C -DPROJECTVERSION=$(GhcProjectVersionInt)
 
 # Heap was 6m with 2.10
 reader/ReadPrefix_HC_OPTS      = -fvia-C '-\#include"hspincl.h"' -H10m
index cfd42a6..f051eef 100644 (file)
@@ -21,7 +21,9 @@ module SrcLoc (
 
        mkGeneratedSrcLoc,      -- Code generated within the compiler
 
-       incSrcLine
+       incSrcLine,
+       
+       srcLocFile              -- return the file name part.
     ) where
 
 #include "HsVersions.h"
@@ -72,6 +74,9 @@ mkGeneratedSrcLoc   = UnhelpfulSrcLoc SLIT("<compiler-generated-code>")
 isNoSrcLoc NoSrcLoc = True
 isNoSrcLoc other    = False
 
+srcLocFile :: SrcLoc -> FAST_STRING
+srcLocFile (SrcLoc fname _) = fname
+
 incSrcLine :: SrcLoc -> SrcLoc
 incSrcLine (SrcLoc s l) = SrcLoc s (l +# 1#)
 incSrcLine loc         = loc
index 255dc59..5b5c213 100644 (file)
@@ -12,7 +12,8 @@ module MkIface (
 
 #include "HsVersions.h"
 
-import IO              ( Handle, hPutStr, openFile, hClose, IOMode(..) )
+import IO              ( Handle, hPutStr, openFile, 
+                         hClose, hPutStrLn, IOMode(..) )
 
 import HsSyn
 import RdrHsSyn                ( RdrName(..) )
@@ -99,9 +100,9 @@ endIface    :: Maybe Handle -> IO ()
 startIface mod
   = case opt_ProduceHi of
       Nothing -> return Nothing -- not producing any .hi file
-      Just fn ->
-       openFile fn WriteMode   >>= \ if_hdl ->
-       hPutStr if_hdl ("{-# GHC_PRAGMA INTERFACE VERSION 20 #-}\n_interface_ "++ _UNPK_ mod ++ "\n") >>
+      Just fn -> do
+       if_hdl <- openFile fn WriteMode
+       hPutStrLn if_hdl ("_interface_ "++ _UNPK_ mod ++ ' ':show (PROJECTVERSION :: Int))
        return (Just if_hdl)
 
 endIface Nothing       = return ()
index 5ce4cc7..ca67c8c 100644 (file)
@@ -25,6 +25,7 @@ module Lex (
 
        -- Monad for parser
        IfaceToken(..), lexIface, IfM, thenIf, returnIf, getSrcLocIf,
+       checkVersion, 
        happyError,
        StringBuffer
 
@@ -33,6 +34,7 @@ module Lex (
 #include "HsVersions.h"
 
 import Char            (isDigit, isAlphanum, isUpper,isLower, isSpace, ord )
+import List             ( isSuffixOf )
 
 import {-# SOURCE #-} CostCentre
 
@@ -40,7 +42,7 @@ import CmdLineOpts    ( opt_IgnoreIfacePragmas )
 import Demand          ( Demand(..) {- instance Read -} )
 import UniqFM           ( UniqFM, listToUFM, lookupUFM)
 import BasicTypes      ( NewOrData(..), IfaceFlavour(..) )
-import SrcLoc          ( SrcLoc, incSrcLine )
+import SrcLoc          ( SrcLoc, incSrcLine, srcLocFile )
 
 import Maybes          ( MaybeErr(..) )
 import ErrUtils                ( ErrMsg(..) )
@@ -872,9 +874,39 @@ getSrcLocIf s l = Succeeded l
 happyError :: IfM a
 happyError s l = Failed (ifaceParseErr l ([]::[IfaceToken]){-Todo-})
 
+
+{- 
+ Note that if the file we're processing ends with `hi-boot',
+ we accept it on faith as having the right version.
+ This is done so that .hi-boot files  that comes with hsc
+ don't have to be updated before every release, and it
+ allows us to share .hi-boot files with versions of hsc
+ that don't have .hi version checking (e.g., ghc-2.10's)
+
+ If the version number is 0, the checking is also turned off.
+-}
+checkVersion :: Maybe Integer -> IfM ()
+checkVersion mb@(Just v) s l
+ | (v==0) || (v == PROJECTVERSION) = Succeeded ()
+ | otherwise = Failed (ifaceVersionErr mb l ([]::[IfaceToken]){-Todo-})
+checkVersion mb@Nothing  s l 
+ | "hi-boot" `isSuffixOf` (_UNPK_ (srcLocFile l)) = Succeeded ()
+ | otherwise = Failed (ifaceVersionErr mb l ([]::[IfaceToken]){-Todo-})
+
 -----------------------------------------------------------------
 
 ifaceParseErr l toks
   = hsep [ppr l, ptext SLIT("Interface-file parse error;"),
           ptext SLIT("toks="), text (show (take 10 toks))]
+
+ifaceVersionErr hi_vers l toks
+  = hsep [ppr l, ptext SLIT("Interface file version error;"),
+          ptext SLIT("Expected"), int PROJECTVERSION, 
+         ptext SLIT(" found "), pp_version]
+    where
+     pp_version =
+      case hi_vers of
+        Nothing -> ptext SLIT("pre ghc-3.02 version")
+       Just v  -> ptext SLIT("version") <+> integer v
+
 \end{code}
index 27f444d..b29cddf 100644 (file)
@@ -125,7 +125,7 @@ iface_stuff : iface         { PIface  $1 }
 
 
 iface          :: { ParsedIface }
-iface          : INTERFACE CONID INTEGER
+iface          : INTERFACE CONID INTEGER checkVersion
                  inst_modules_part 
                  usages_part
                  exports_part fixities_part
@@ -134,12 +134,12 @@ iface             : INTERFACE CONID INTEGER
                  { ParsedIface 
                        $2                      -- Module name
                        (fromInteger $3)        -- Module version
-                       $5                      -- Usages
-                       $6                      -- Exports
-                       $4                      -- Instance modules
-                       $7                      -- Fixities
-                       $9                      -- Decls
-                       $8                      -- Local instances
+                       $6                      -- Usages
+                       $7                      -- Exports
+                       $5                      -- Instance modules
+                       $8                      -- Fixities
+                       $10                     -- Decls
+                       $9                      -- Local instances
                    }
 
 
@@ -607,12 +607,15 @@ prim_rep  :: { Char }
          : VARID                                               { head (_UNPK_ $1) }
          | CONID                                               { head (_UNPK_ $1) }
 
-
 -------------------------------------------------------------------
 
 src_loc :: { SrcLoc }
 src_loc :                              {% getSrcLocIf }
 
+checkVersion :: { () }
+          : {-empty-}                  {% checkVersion Nothing }
+          | INTEGER                    {% checkVersion (Just (fromInteger $1)) }
+
 ------------------------------------------------------------------- 
 
 --                     Haskell code 
index 259b90d..5a98a5b 100644 (file)
@@ -50,10 +50,12 @@ import Outputable
 \begin{code}
 renameModule :: UniqSupply
             -> RdrNameHsModule
-            -> IO (Maybe (RenamedHsModule,     -- Output, after renaming
-                          InterfaceDetails,    -- Interface; for interface file generatino
-                          RnNameSupply,        -- Final env; for renaming derivings
-                          [Module]))           -- Imported modules; for profiling
+            -> IO (Maybe 
+                     ( RenamedHsModule   -- Output, after renaming
+                     , InterfaceDetails  -- Interface; for interface file generatino
+                     , RnNameSupply      -- Final env; for renaming derivings
+                     , [Module]          -- Imported modules; for profiling
+                     ))
 
 renameModule us this_mod@(HsModule mod_name vers exports imports fixities local_decls loc)
   =    -- Initialise the renamer monad
index 0fd3fb1..d72f128 100644 (file)
@@ -114,7 +114,7 @@ sub constructNewHiFile {
     }
 
     local($new_module_version) = &calcNewModuleVersion(@decl_names);
-    print NEWHI "_interface_ ", $ModuleName{'new'}, " $new_module_version\n";
+    print NEWHI "_interface_ ", $ModuleName{'new'}, " $new_module_version $GhcVersionInfo\n";
 
     if ( $Stuff{'new:instance_modules'} ) {
        print NEWHI "_instance_modules_\n";
@@ -199,11 +199,11 @@ sub readHiFile {
            last hi_line;
        }
 
-       if ( /^_interface_ ([A-Z]\S*) (\d+)/ ) {
+       if ( /^_interface_ ([A-Z]\S*) (\d+)/ && $mod ne 'new' ) {
            $ModuleName{$mod}    = $1; # used to decide name of interface file.
            $ModuleVersion{$mod} = $2;
 
-       } elsif ( /^_interface_ ([A-Z]\S*)/ && $mod eq 'new' ) { # special case: no version
+       } elsif ( /^_interface_ ([A-Z]\S*) (\d+)/ && $mod eq 'new' ) { # special case: no version
            $ModuleName{'new'} = $1;
 
        } elsif ( /^_([a-z_]+)_$/ ) {
index 9d8a1b2..d133530 100644 (file)
@@ -5,7 +5,7 @@
 --     primitive operations and types that GHC knows about.
 ---------------------------------------------------------------------------
 
-_interface_ PrelGHC 2
+_interface_ PrelGHC 2 0
 _exports_
 PrelGHC
   ->