[project @ 2001-11-05 14:08:28 by chak]
[ghc-hetmet.git] / ghc / compiler / rename / ParseIface.y
index 30c1478..976d3b0 100644 (file)
@@ -1,46 +1,84 @@
+{-     Notes about the syntax of interface files
+       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The header
+~~~~~~~~~~
+  interface "edison" M 4 6 2 ! 406     Module M, version 4, from package 'edison',
+                                       Fixities version 6, rules version 2
+                                       Interface syntax version 406
+                                       ! means M contains orphans
+
+Import declarations
+~~~~~~~~~~~~~~~~~~~
+  import Foo ;                         To compile M I used nothing from Foo, but it's 
+                                       below me in the hierarchy
+
+  import Foo ! @ ;                     Ditto, but the ! means that Foo contains orphans
+                                       and        the @ means that Foo is a boot interface
+
+  import Foo :: 3 ;                    To compile M I used everything from Foo, which has 
+                                       module version 3
+
+  import Foo :: 3 2 6 a 1 b 3 c 7 ;    To compile M I used Foo.  It had 
+                                               module version 3
+                                               fixity version 2
+                                               rules  version 6
+                                       and some specific things besides.
+
+-}
+
+
 {
-module ParseIface ( parseIface, IfaceStuff(..) ) where
+module ParseIface ( parseIface, parseType, parseRules, parseIdInfo ) where
 
 #include "HsVersions.h"
 
 import HsSyn           -- quite a bit of stuff
 import RdrHsSyn                -- oodles of synonyms
-import HsDecls         ( HsIdInfo(..), HsStrictnessInfo(..) )
-import HsTypes         ( mkHsForAllTy )
+import HsTypes         ( mkHsForAllTy, mkHsTupCon )
 import HsCore
-import Const           ( Literal(..), mkMachInt_safe )
-import BasicTypes      ( IfaceFlavour(..), Fixity(..), FixityDirection(..), 
-                         NewOrData(..), Version
+import Literal         ( Literal(..), mkMachInt, mkMachInt64, mkMachWord, mkMachWord64 )
+import BasicTypes      ( Fixity(..), FixityDirection(..), StrictnessMark(..),
+                         NewOrData(..), Version, initialVersion, Boxity(..),
+                          Activation(..)
                        )
-import HsPragmas       ( noDataPragmas, noClassPragmas )
-import Type            ( Kind, mkArrowKind, boxedTypeKind, openTypeKind )
-import IdInfo           ( ArityInfo, exactArity )
+import CostCentre       ( CostCentre(..), IsCafCC(..), IsDupdCC(..) )
+import Type            ( Kind, mkArrowKind, liftedTypeKind, openTypeKind, usageTypeKind )
+import IdInfo           ( InlinePragInfo(..) )
+import ForeignCall     ( ForeignCall(..), CCallConv(..), CCallSpec(..), CCallTarget(..) )
 import Lex             
 
-import RnEnv            ( ifaceUnqualTC, ifaceUnqualVar, ifaceUnqualTv, ifaceQualVar, ifaceQualTC )
-import RnMonad         ( ImportVersion, LocalVersion, ParsedIface(..), WhatsImported(..),
-                         RdrNamePragma, ExportItem, RdrAvailInfo, GenAvailInfo(..)
-                       ) 
-import Bag             ( emptyBag, unitBag, snocBag )
-import FiniteMap       ( emptyFM, unitFM, addToFM, plusFM, bagToFM, FiniteMap )
-import Name            ( OccName, isTCOcc, Provenance, Module,
-                         varOcc, tcOcc, mkModuleFS
+import RnMonad         ( ParsedIface(..), ExportItem, IfaceDeprecs ) 
+import HscTypes         ( WhetherHasOrphans, IsBootInterface, GenAvailInfo(..), 
+                          ImportVersion, WhatsImported(..),
+                          RdrAvailInfo )
+
+import RdrName          ( RdrName, mkRdrUnqual, mkIfaceOrig )
+import Name            ( OccName )
+import OccName          ( mkSysOccFS,
+                         tcName, varName, dataName, clsName, tvName,
+                         EncodedFS 
                        )
-import PrelMods         ( mkTupNameStr, mkUbxTupNameStr )
-import PrelInfo         ( mkTupConRdrName, mkUbxTupConRdrName )
+import Module           ( ModuleName, PackageName, mkSysModuleNameFS, mkModule )
 import SrcLoc          ( SrcLoc )
-import Maybes
+import CmdLineOpts     ( opt_InPackage, opt_IgnoreIfacePragmas )
 import Outputable
+import Class            ( DefMeth (..) )
 
 import GlaExts
+import FastString      ( tailFS )
 }
 
-%name      parseIface
-%tokentype  { IfaceToken }
-%monad     { IfM }{ thenIf }{ returnIf }
-%lexer      { lexIface } { ITeof }
+%name      parseIface      iface
+%name      parseType       type
+%name      parseIdInfo     id_info
+%name      parseRules      rules_and_deprecs
+
+%tokentype  { Token }
+%monad     { P }{ thenP }{ returnP }
+%lexer      { lexer } { ITeof }
 
 %token
+ 'as'          { ITas }
  'case'        { ITcase }                      -- Haskell keywords
  'class'       { ITclass } 
  'data'        { ITdata } 
@@ -48,6 +86,7 @@ import GlaExts
  'deriving'    { ITderiving }
  'do'          { ITdo }
  'else'        { ITelse }
+ 'hiding'      { IThiding }
  'if'          { ITif }
  'import'      { ITimport }
  'in'          { ITin }
@@ -59,37 +98,55 @@ import GlaExts
  'module'      { ITmodule }
  'newtype'     { ITnewtype }
  'of'          { ITof }
+ 'qualified'   { ITqualified }
  'then'        { ITthen }
  'type'        { ITtype }
  'where'       { ITwhere }
- 'as'          { ITas }
- 'qualified'   { ITqualified }
- 'hiding'      { IThiding }
 
- '__interface' { ITinterface }                 -- GHC-extension keywords
- '__export'    { ITexport }
- '__instimport'        { ITinstimport }
- '__forall'    { ITforall }
+ 'forall'      { ITforall }                    -- GHC extension keywords
+ 'foreign'     { ITforeign }
+ 'export'      { ITexport }
+ 'label'       { ITlabel } 
+ 'dynamic'     { ITdynamic }
+ 'unsafe'      { ITunsafe }
+ 'with'                { ITwith }
+ 'stdcall'      { ITstdcallconv }
+ 'ccall'        { ITccallconv }
+
+ '__interface' { ITinterface }                 -- interface keywords
+ '__export'    { IT__export }
+ '__depends'   { ITdepends }
+ '__forall'    { IT__forall }
  '__letrec'    { ITletrec }
  '__coerce'    { ITcoerce }
- '__inline'    { ITinline }
+ '__inline_me'  { ITinlineMe }
+ '__inline_call'{ ITinlineCall }
  '__DEFAULT'   { ITdefaultbranch }
  '__bot'       { ITbottom }
  '__integer'   { ITinteger_lit }
  '__float'     { ITfloat_lit }
+ '__word'      { ITword_lit }
+ '__int64'     { ITint64_lit }
+ '__word64'    { ITword64_lit }
  '__rational'  { ITrational_lit }
  '__addr'      { ITaddr_lit }
+ '__label'     { ITlabel_lit }
  '__litlit'    { ITlit_lit }
  '__string'    { ITstring_lit }
  '__ccall'     { ITccall $$ }
- '__scc'       { ITscc $$ }
- '__a'         { ITtypeapp }
+ '__scc'       { ITscc }
+ '__sccC'       { ITsccAllCafs }
+
+ '__u'         { ITusage }
 
  '__A'         { ITarity }
  '__P'         { ITspecialise }
  '__C'         { ITnocaf }
- '__U'         { ITunfold $$ }
+ '__U'         { ITunfold }
  '__S'         { ITstrict $$ }
+ '__R'         { ITrules }
+ '__M'         { ITcprinfo }
+ '__D'         { ITdeprecated }
 
  '..'          { ITdotdot }                    -- reserved symbols
  '::'          { ITdcolon }
@@ -99,15 +156,14 @@ import GlaExts
  '<-'          { ITlarrow }
  '->'          { ITrarrow }
  '@'           { ITat }
- '~'           { ITtilde }
  '=>'          { ITdarrow }
  '-'           { ITminus }
  '!'           { ITbang }
 
- '/\\'         { ITbiglam }                    -- GHC-extension symbols
-
  '{'           { ITocurly }                    -- special symbols
  '}'           { ITccurly }
+ '{|'          { ITocurlybar }                         -- special symbols
+ '|}'          { ITccurlybar }                         -- special symbols
  '['           { ITobrack }
  ']'           { ITcbrack }
  '('           { IToparen }
@@ -116,6 +172,7 @@ import GlaExts
  '#)'          { ITcubxparen }
  ';'           { ITsemi }
  ','           { ITcomma }
+ '.'           { ITdot }
 
  VARID         { ITvarid    $$ }               -- identifiers
  CONID         { ITconid    $$ }
@@ -126,105 +183,130 @@ import GlaExts
  QVARSYM       { ITqvarsym  $$ }
  QCONSYM       { ITqconsym  $$ }
 
+ IPVARID       { ITipvarid  $$ }               -- GHC extension
+
  PRAGMA                { ITpragma   $$ }
 
  CHAR          { ITchar     $$ }
  STRING                { ITstring   $$ }
  INTEGER       { ITinteger  $$ }
  RATIONAL      { ITrational $$ }
+ CLITLIT       { ITlitlit   $$ }
 
  UNKNOWN       { ITunknown  $$ }
 %%
 
--- iface_stuff is the main production.
--- It recognises (a) a whole interface file
---              (b) a type (so that type sigs can be parsed lazily)
---              (c) the IdInfo part of a signature (same reason)
-
-iface_stuff :: { IfaceStuff }
-iface_stuff : iface            { PIface  $1 }
-           | type              { PType   $1 }
-           | id_info           { PIdInfo $1 }
-
-
 iface          :: { ParsedIface }
-iface          : '__interface' mod_name INTEGER checkVersion 'where'
-                  import_part
-                 instance_import_part
+iface          : '__interface' package mod_name 
+                       version sub_versions
+                       orphans checkVersion 'where'
                  exports_part
+                  import_part
+                 fix_decl_part
                  instance_decl_part
                  decls_part
-                 { ParsedIface 
-                       $2                      -- Module name
-                       (fromInteger $3)        -- Module version
-                       (reverse $6)            -- Usages
-                       (reverse $8)            -- Exports
-                       (reverse $7)            -- Instance import modules
-                       (reverse $10)           -- Decls
-                       (reverse $9)            -- Local instances
-                 }
+                 rules_and_deprecs_part
+                 { ParsedIface {
+                       pi_mod  = mkModule $3 $2,       -- Module itself
+                       pi_vers = $4,                   -- Module version
+                       pi_orphan  = $6,
+                       pi_exports = (fst $5, $9),      -- Exports
+                       pi_usages  = $10,               -- Usages
+                       pi_fixity  = $11,               -- Fixies
+                       pi_insts   = $12,               -- Local instances
+                       pi_decls   = $13,               -- Decls
+                       pi_rules   = (snd $5,fst $14),  -- Rules 
+                       pi_deprecs = snd $14            -- Deprecations 
+                  } }
+
+-- Versions for exports and rules (optional)
+sub_versions :: { (Version,Version) }
+       : '[' version version ']'               { ($2,$3) }
+       | {- empty -}                           { (initialVersion, initialVersion) }
 
 --------------------------------------------------------------------------
 
 import_part :: { [ImportVersion OccName] }
 import_part :                                            { [] }
-           |  import_part import_decl                    { $2 : $1 }
+           |  import_decl import_part                    { $1 : $2 }
            
 import_decl :: { ImportVersion OccName }
-import_decl : 'import' mod_name opt_bang INTEGER '::' whats_imported ';'
-                       { ($2, $3, fromInteger $4, $6) }
+import_decl : 'import' mod_name orphans is_boot whats_imported ';'
+                       { ({-mkSysModuleNameFS-} $2, $3, $4, $5) }
+
+orphans                    :: { WhetherHasOrphans }
+orphans                    :                                           { False }
+                   | '!'                                       { True }
+
+is_boot                    :: { IsBootInterface }
+is_boot                    :                                           { False }
+                   | '@'                                       { True }
 
 whats_imported      :: { WhatsImported OccName }
-whats_imported      :                                           { Everything }
-                    | name_version_pair name_version_pairs      { Specifically ($1:$2) }
+whats_imported      :                                                  { NothingAtAll }
+                   | '::' version                                      { Everything $2 }
+                    | '::' version version version name_version_pairs   { Specifically $2 (Just $3) $5 $4 }
+                    | '::' version version name_version_pairs          { Specifically $2 Nothing $4 $3 }
 
-name_version_pairs  :: { [LocalVersion OccName] }
+name_version_pairs  :: { [(OccName, Version)] }
 name_version_pairs  :                                                  { [] }
                    |  name_version_pair name_version_pairs     { $1 : $2 }
 
-name_version_pair   :: { LocalVersion OccName }
-name_version_pair   :  entity_occ INTEGER                      { ($1, fromInteger $2) }
+name_version_pair   :: { (OccName, Version) }
+name_version_pair   :  var_occ version                         { ($1, $2) }
+                    |  tc_occ  version                          { ($1, $2) }
 
-instance_import_part :: { [Module] }
-instance_import_part :                                                 {   []    }
-                     | instance_import_part '__instimport' mod_name ';'
-                                                               { $3 : $1 }
 
 --------------------------------------------------------------------------
 
 exports_part   :: { [ExportItem] }
 exports_part   :                                       { [] }
-               | exports_part '__export' opt_bang mod_name entities ';'
-                                               { ($4,$3,$5) : $1 }
-
-opt_bang       :: { IfaceFlavour }
-opt_bang       :                                               { HiFile }
-               | '!'                                           { HiBootFile }
+               | '__export' mod_name entities ';'
+                       exports_part                    { ({-mkSysModuleNameFS-} $2, $3) : $5 }
 
 entities       :: { [RdrAvailInfo] }
-entities       :                                               { [] }
-               |  entity entities                              { $1 : $2 }
+entities       :                                       { [] }
+               |  entity entities                      { $1 : $2 }
 
 entity         :: { RdrAvailInfo }
-entity         :  entity_occ                           { if isTCOcc $1 
-                                                         then AvailTC $1 [$1]
-                                                         else Avail $1 }
-               |  entity_occ stuff_inside              { AvailTC $1 ($1:$2) }
-               |  entity_occ '|' stuff_inside          { AvailTC $1 $3 }
+entity         :  var_occ                              { Avail $1 }
+               |  tc_occ                               { AvailTC $1 [$1] }
+               |  tc_occ '|' stuff_inside              { AvailTC $1 $3 }
+               |  tc_occ stuff_inside                  { AvailTC $1 ($1:$2) }
+               -- Note that the "main name" comes at the beginning
 
 stuff_inside   :: { [OccName] }
 stuff_inside   :  '{' val_occs '}'                     { $2 }
 
+val_occ                :: { OccName }
+               :  var_occ              { $1 }
+                |  data_occ             { $1 }
+
+val_occs       :: { [OccName] }
+               :  val_occ              { [$1] }
+               |  val_occ val_occs     { $1 : $2 }
+
+
 --------------------------------------------------------------------------
 
+fix_decl_part :: { [RdrNameFixitySig] }
+fix_decl_part : {- empty -}                            { [] }
+             | fix_decls ';'                           { $1 }
+
+fix_decls     :: { [RdrNameFixitySig] }
+fix_decls     :                                        { [] }
+             | fix_decl fix_decls                      { $1 : $2 }
+
+fix_decl :: { RdrNameFixitySig }
+fix_decl : src_loc fixity prec var_or_data_name                { FixitySig $4 (Fixity $3 $2) $1 }
+
 fixity      :: { FixityDirection }
 fixity      : 'infixl'                                  { InfixL }
             | 'infixr'                                  { InfixR }
             | 'infix'                                   { InfixN }
    
-mb_fix      :: { Int }
-mb_fix     : {-nothing-}                               { 9 }
-           | INTEGER                                   { (fromInteger $1) }
+prec        :: { Int }
+prec       : INTEGER                                   { fromInteger $1 }
 
 -----------------------------------------------------------------------------
 
@@ -233,15 +315,13 @@ csigs             :                               { [] }
                | 'where' '{' csigs1 '}'        { $3 }
 
 csigs1         :: { [RdrNameSig] }
-csigs1         : csig                          { [$1] }
+csigs1         :                               { [] }
                | csig ';' csigs1               { $1 : $3 }
 
 csig           :: { RdrNameSig }
-csig           :  src_loc var_name '::' type { ClassOpSig $2 Nothing $4 $1 }
-               |  src_loc var_name '=' '::' type       
-                       { ClassOpSig $2 
-                           (Just (error "Un-filled-in default method"))
-                           $5 $1 }
+csig           :  src_loc qvar_name '::' type          { ClassOpSig $2 NoDefMeth $4 $1 }
+               |  src_loc qvar_name ';' '::' type      { ClassOpSig $2 GenDefMeth $5 $1 }              
+               |  src_loc qvar_name '=' '::' type      { mkClassOpSigDM $2 $5 $1 }
 
 --------------------------------------------------------------------------
 
@@ -250,7 +330,7 @@ instance_decl_part : {- empty -}                   { [] }
                   | instance_decl_part inst_decl      { $2 : $1 }
 
 inst_decl      :: { RdrNameInstDecl }
-inst_decl      :  src_loc 'instance' type '=' var_name ';'
+inst_decl      :  src_loc 'instance' type '=' qvar_name ';'
                        { InstDecl $3
                                   EmptyMonoBinds       {- No bindings -}
                                   []                   {- No user pragmas -}
@@ -260,45 +340,133 @@ inst_decl        :  src_loc 'instance' type '=' var_name ';'
 
 --------------------------------------------------------------------------
 
-decls_part :: { [(Version, RdrNameHsDecl)] }
+decls_part :: { [(Version, RdrNameTyClDecl)] }
 decls_part 
        :  {- empty -}                          { [] }
-       |  decls_part version decl ';'          { ($2,$3):$1 }
-
-decl   :: { RdrNameHsDecl }
-decl    : src_loc var_name '::' type maybe_idinfo
-                        { SigD (IfaceSig $2 $4 ($5 $2) $1) }
-       | src_loc 'type' tc_name tv_bndrs '=' type                     
-                       { TyClD (TySynonym $3 $4 $6 $1) }
-       | src_loc 'data' decl_context data_fs tv_bndrs constrs         
-                       { TyClD (TyData DataType $3 (ifaceUnqualTC $4) $5 $6 Nothing noDataPragmas $1) }
-       | src_loc 'newtype' decl_context tc_name tv_bndrs newtype_constr
-                       { TyClD (TyData NewType $3 $4 $5 $6 Nothing noDataPragmas $1) }
-       | src_loc 'class' decl_context tc_name tv_bndrs csigs
-                       { TyClD (mkClassDecl $3 $4 $5 $6 EmptyMonoBinds 
-                                       noClassPragmas $1) }
-        | src_loc fixity mb_fix val_occ
-                        { FixD (FixitySig (Unqual $4) (Fixity $3 $2) $1) }
+       |  opt_version decl ';' decls_part              { ($1,$2):$4 }
+
+decl   :: { RdrNameTyClDecl }
+decl    : src_loc qvar_name '::' type maybe_idinfo
+                       { IfaceSig $2 $4 ($5 $2) $1 }
+       | src_loc 'type' qtc_name tv_bndrs '=' type                    
+                       { TySynonym $3 $4 $6 $1 }
+       | src_loc 'foreign' 'type' qtc_name                    
+                       { ForeignType $4 Nothing DNType $1 }
+       | src_loc 'data' opt_decl_context qtc_name tv_bndrs constrs            
+                       { mkTyData DataType $3 $4 $5 $6 (length $6) Nothing $1 }
+       | src_loc 'newtype' opt_decl_context qtc_name tv_bndrs newtype_constr
+                       { mkTyData NewType $3 $4 $5 $6 1 Nothing $1 }
+       | src_loc 'class' opt_decl_context qtc_name tv_bndrs fds csigs
+                       { mkClassDecl $3 $4 $5 $6 $7 Nothing $1 }
 
 maybe_idinfo  :: { RdrName -> [HsIdInfo RdrName] }
 maybe_idinfo  : {- empty -}    { \_ -> [] }
-             | src_loc PRAGMA  { \x -> 
-                                  case parseIface $2 $1 of
-                                    Succeeded (PIdInfo id_info) -> id_info
-                                    Failed err -> pprPanic "IdInfo parse failed" 
-                                                           (vcat [ppr x, err])
+             | pragma          { \x -> if opt_IgnoreIfacePragmas then [] 
+                                       else case $1 of
+                                               POk _ id_info -> id_info
+                                               PFailed err -> pprPanic "IdInfo parse failed" 
+                                                                       (vcat [ppr x, err])
+                               }
+    {-
+      If a signature decl is being loaded, and opt_IgnoreIfacePragmas is on,
+      we toss away unfolding information.
+
+      Also, if the signature is loaded from a module we're importing from source,
+      we do the same. This is to avoid situations when compiling a pair of mutually
+      recursive modules, peering at unfolding info in the interface file of the other, 
+      e.g., you compile A, it looks at B's interface file and may as a result change
+      its interface file. Hence, B is recompiled, maybe changing its interface file,
+      which will the unfolding info used in A to become invalid. Simple way out is to
+      just ignore unfolding info.
+
+      [Jan 99: I junked the second test above.  If we're importing from an hi-boot
+       file there isn't going to *be* any pragma info.  The above comment
+       dates from a time where we picked up a .hi file first if it existed.]
+    -}
+
+pragma :: { ParseResult [HsIdInfo RdrName] }
+pragma : src_loc PRAGMA        { parseIdInfo $2 PState{ bol = 0#, atbol = 1#,
+                                                       context = [],
+                                                       glasgow_exts = 1#,
+                                                       loc = $1 }
                                }
 
 -----------------------------------------------------------------------------
 
+rules_and_deprecs_part :: { ([RdrNameRuleDecl], IfaceDeprecs) }
+rules_and_deprecs_part : {- empty -}   { ([], Nothing) }
+                      | rules_prag     { case $1 of
+                                            POk _ rds -> rds
+                                            PFailed err -> pprPanic "Rules/Deprecations parse failed" err
+                                       }
+
+rules_prag :: { ParseResult ([RdrNameRuleDecl], IfaceDeprecs) }
+rules_prag : src_loc PRAGMA    { parseRules $2 PState{ bol = 0#, atbol = 1#,
+                                                       context = [],
+                                                       glasgow_exts = 1#,
+                                                       loc = $1 }
+                               }
+
+rules_and_deprecs :: { ([RdrNameRuleDecl], IfaceDeprecs) }
+rules_and_deprecs : rule_prag deprec_prag      { ($1, $2) }
+
+-----------------------------------------------------------------------------
+
+rule_prag :: { [RdrNameRuleDecl] }
+rule_prag : {- empty -}                        { [] }
+         | '__R' rules                 { $2 }
+
+rules     :: { [RdrNameRuleDecl] }
+          : {- empty -}        { [] }
+          | rule ';' rules     { $1:$3 }
+
+rule      :: { RdrNameRuleDecl }
+rule      : src_loc STRING activation rule_forall qvar_name 
+            core_args '=' core_expr    { IfaceRule $2 $3 $4 $5 $6 $8 $1 } 
+
+activation :: { Activation }
+activation : {- empty -}                { AlwaysActive }
+           | '[' INTEGER ']'            { ActiveAfter (fromInteger $2) }
+
+rule_forall    :: { [UfBinder RdrName] }
+rule_forall    : '__forall' '{' core_bndrs '}' { $3 }
+                 
+-----------------------------------------------------------------------------
+
+deprec_prag    :: { IfaceDeprecs }
+deprec_prag    : {- empty -}           { Nothing }
+               | '__D' deprecs         { Just $2 } 
+
+deprecs        :: { Either DeprecTxt [(RdrName,DeprecTxt)] }
+deprecs                : STRING                { Left $1 }
+               | deprec_list           { Right $1 }
+
+deprec_list    :: { [(RdrName,DeprecTxt)] }
+deprec_list    : deprec                        { [$1] }
+               | deprec ';' deprec_list        { $1 : $3 }
+
+deprec         :: { (RdrName,DeprecTxt) }
+deprec         : deprec_name STRING    { ($1, $2) }
+
+deprec_name    :: { RdrName }
+               : qvar_name             { $1 }
+               | qtc_name              { $1 }
+
+-----------------------------------------------------------------------------
+
 version                :: { Version }
-version                :  INTEGER                              { fromInteger $1 }
+version                :  INTEGER                      { fromInteger $1 }
 
-decl_context   :: { RdrNameContext }
-decl_context   :                                       { [] }
-               | '{' context_list1 '}' '=>'    { $2 }
+opt_version    :: { Version }
+opt_version    : version                       { $1 }
+               | {- empty -}                   { initialVersion }
+       
+opt_decl_context  :: { RdrNameContext }
+opt_decl_context  :                            { [] }
+                 | context '=>'                { $1 }
 
-----------------------------------------------------------------
+----------------------------------------------------------------------------
 
 constrs                :: { [RdrNameConDecl] {- empty for handwritten abstract -} }
                :                       { [] }
@@ -309,56 +477,65 @@ constrs1  :  constr               { [$1] }
                |  constr '|' constrs1  { $1 : $3 }
 
 constr         :: { RdrNameConDecl }
-constr         :  src_loc ex_stuff data_fs batypes             { mkConDecl (ifaceUnqualVar $3) $2 (VanillaCon $4) $1 }
-               |  src_loc ex_stuff data_fs '{' fields1 '}'     { mkConDecl (ifaceUnqualVar $3) $2 (RecCon $5)     $1 }
+constr         :  src_loc ex_stuff qdata_name batypes          { mk_con_decl $3 $2 (VanillaCon $4) $1 }
+               |  src_loc ex_stuff qdata_name '{' fields1 '}'  { mk_con_decl $3 $2 (RecCon $5)     $1 }
                 -- We use "data_fs" so as to include ()
 
-newtype_constr :: { [RdrNameConDecl] {- Empty if handwritten abstract -} }
-newtype_constr :                                       { [] }
-               | src_loc '=' ex_stuff data_name atype  { [mkConDecl $4 $3 (NewCon $5 Nothing) $1] }
-               | src_loc '=' ex_stuff data_name '{' var_name '::' atype '}'
-                                                       { [mkConDecl $4 $3 (NewCon $8 (Just $6)) $1] }
+newtype_constr :: { [RdrNameConDecl] {- Not allowed to be empty -} }
+newtype_constr : src_loc '=' ex_stuff qdata_name atype { [mk_con_decl $4 $3 (VanillaCon [unbangedType $5]) $1] }
+               | src_loc '=' ex_stuff qdata_name '{' qvar_name '::' atype '}'
+                                                       { [mk_con_decl $4 $3 (RecCon [([$6], unbangedType $8)]) $1] }
 
-ex_stuff :: { ([HsTyVar RdrName], RdrNameContext) }
+ex_stuff :: { ([HsTyVarBndr RdrName], RdrNameContext) }
 ex_stuff       :                                       { ([],[]) }
-                | '__forall' forall context '=>'            { ($2,$3) }
+                | '__forall' tv_bndrs opt_context '=>'  { ($2,$3) }
 
 batypes                :: { [RdrNameBangType] }
 batypes                :                                       { [] }
                |  batype batypes                       { $1 : $2 }
 
 batype         :: { RdrNameBangType }
-batype         :  atype                                { Unbanged $1 }
-               |  '!' atype                            { Banged   $2 }
+batype         :  tatype                               { unbangedType $1 }
+               |  '!' tatype                           { BangType MarkedStrict    $2 }
+               |  '!' '!' tatype                       { BangType MarkedUnboxed   $3 }
 
 fields1                :: { [([RdrName], RdrNameBangType)] }
 fields1                : field                                 { [$1] }
                | field ',' fields1                     { $1 : $3 }
 
 field          :: { ([RdrName], RdrNameBangType) }
-field          :  var_names1 '::' type         { ($1, Unbanged $3) }
-               |  var_names1 '::' '!' type     { ($1, Banged   $4) }
+field          :  qvar_names1 '::' ttype               { ($1, unbangedType $3) }
+               |  qvar_names1 '::' '!' ttype           { ($1, BangType MarkedStrict    $4) }
+               |  qvar_names1 '::' '!' '!' ttype       { ($1, BangType MarkedUnboxed   $5) }
+
 --------------------------------------------------------------------------
 
 type           :: { RdrNameHsType }
-type           : '__forall' forall context '=>' type   
-                                               { mkHsForAllTy $2 $3 $5 }
-               | btype '->' type               { MonoFunTy $1 $3 }
+type           : '__forall' tv_bndrs 
+                       opt_context '=>' type   { mkHsForAllTy (Just $2) $3 $5 }
+               | btype '->' type               { HsFunTy $1 $3 }
                | btype                         { $1 }
 
-forall         :: { [HsTyVar RdrName] }
-forall         : '[' tv_bndrs ']'                      { $2 }
+opt_context    :: { RdrNameContext }
+opt_context    :                                       { [] }
+               | context                               { $1 }
 
 context                :: { RdrNameContext }
-context                :                                       { [] }
-               | '{' context_list1 '}'                 { $2 }
+context                : '(' context_list1 ')'                 { $2 }
+               | '{' context_list1 '}'                 { $2 }  -- Backward compatibility
 
 context_list1  :: { RdrNameContext }
 context_list1  : class                                 { [$1] }
                | class ',' context_list1               { $1 : $3 }
 
-class          :: { (RdrName, [RdrNameHsType]) }
-class          :  qtc_name atypes                      { ($1, $2) }
+class          :: { HsPred RdrName }
+class          :  qcls_name atypes                     { (HsClassP $1 $2) }
+               |  ipvar_name '::' type                 { (HsIParam $1 $3) }
+
+types0         :: { [RdrNameHsType]                    {- Zero or more -}  }   
+types0         :  {- empty -}                          { [ ] }
+               |  type                                 { [ $1 ] }
+               |  types2                               { $1 }
 
 types2         :: { [RdrNameHsType]                    {- Two or more -}  }    
 types2         :  type ',' type                        { [$1,$3] }
@@ -366,64 +543,96 @@ types2            :  type ',' type                        { [$1,$3] }
 
 btype          :: { RdrNameHsType }
 btype          :  atype                                { $1 }
-               |  btype atype                          { MonoTyApp $1 $2 }
+               |  btype atype                          { HsAppTy $1 $2 }
+               |  '__u' atype atype                    { HsUsageTy $2 $3 }
 
 atype          :: { RdrNameHsType }
-atype          :  qtc_name                             { MonoTyVar $1 }
-               |  tv_name                              { MonoTyVar $1 }
-               |  '(' ')'                              { MonoTupleTy [] True }
-               |  '(' types2 ')'                       { MonoTupleTy $2 True{-boxed-} }
-               |  '(#' type '#)'                       { MonoTupleTy [$2] False{-unboxed-} }
-               |  '(#' types2 '#)'                     { MonoTupleTy $2 False{-unboxed-} }
-               |  '[' type ']'                         { MonoListTy  $2 }
-               |  '{' qtc_name atypes '}'              { MonoDictTy $2 $3 }
+atype          :  qtc_name                             { HsTyVar $1 }
+               |  tv_name                              { HsTyVar $1 }
+               |  '.'                                  { hsUsOnce }
+               |  '!'                                  { hsUsMany }
+               |  '(' ')'                              { HsTupleTy (mkHsTupCon tcName Boxed   []) [] }
+               |  '(' types2 ')'                       { HsTupleTy (mkHsTupCon tcName Boxed   $2) $2 }
+               |  '(#' types0 '#)'                     { HsTupleTy (mkHsTupCon tcName Unboxed $2) $2 }
+               |  '[' type ']'                         { HsListTy  $2 }
+               |  '{' qcls_name atypes '}'             { mkHsDictTy $2 $3 }
+               |  '{' ipvar_name '::' type '}'         { mkHsIParamTy $2 $4 }
                |  '(' type ')'                         { $2 }
 
 atypes         :: { [RdrNameHsType]    {-  Zero or more -} }
 atypes         :                                       { [] }
                |  atype atypes                         { $1 : $2 }
----------------------------------------------------------------------
+--------------------------------------------------------------------------
 
-mod_name       :: { Module }
-               :  CONID                { mkModuleFS $1 }
+-- versions of type/btype/atype that cant begin with '!' (or '.')
+-- for use where the kind is definitely known NOT to be '$'
+
+ttype          :: { RdrNameHsType }
+ttype          : '__forall' tv_bndrs 
+                       opt_context '=>' type           { mkHsForAllTy (Just $2) $3 $5 }
+               | tbtype '->' type                      { HsFunTy $1 $3 }
+               | tbtype                                { $1 }
+
+tbtype         :: { RdrNameHsType }
+tbtype         :  tatype                               { $1 }
+               |  tbtype atype                         { HsAppTy $1 $2 }
+               |  '__u' atype atype                    { HsUsageTy $2 $3 }
+
+tatype         :: { RdrNameHsType }
+tatype         :  qtc_name                             { HsTyVar $1 }
+               |  tv_name                              { HsTyVar $1 }
+               |  '(' ')'                              { HsTupleTy (mkHsTupCon tcName Boxed   []) [] }
+               |  '(' types2 ')'                       { HsTupleTy (mkHsTupCon tcName Boxed   $2) $2 }
+               |  '(#' types0 '#)'                     { HsTupleTy (mkHsTupCon tcName Unboxed $2) $2 }
+               |  '[' type ']'                         { HsListTy  $2 }
+               |  '{' qcls_name atypes '}'             { mkHsDictTy $2 $3 }
+               |  '{' ipvar_name '::' type '}'         { mkHsIParamTy $2 $4 }
+               |  '(' type ')'                         { $2 }
+---------------------------------------------------------------------
 
-var_fs         :: { FAST_STRING }
-               : VARID                 { $1 }
-               | VARSYM                { $1 }
-               | '-'                   { SLIT("-") }
-               | '!'                   { SLIT("!") }
-
-data_fs         :: { FAST_STRING }
-               :  CONID                { $1 }
-               |  CONSYM               { $1 }
-               |  '->'                 { SLIT("->") }
-                |  '(' ')'             { SLIT("()") }
-               |  '(' commas ')'       { snd (mkTupNameStr $2) }
-               |  '[' ']'              { SLIT("[]") }
-
-commas         :: { Int }
-               : ','                   { 2 }
-               | commas ','            { $1 + 1 }
+package                :: { PackageName }
+               :  STRING               { $1 }
+               | {- empty -}           { opt_InPackage }
+                               -- Useful for .hi-boot files,
+                               -- which can omit the package Id
+                               -- Module loops are always within a package
 
-val_occ                :: { OccName }
-               :  var_fs               { varOcc $1 }
-                |  data_fs              { varOcc $1 }
+mod_name       :: { ModuleName }
+               :  CONID                { mkSysModuleNameFS $1 }
 
-val_occs       :: { [OccName] }
-               :  val_occ              { [$1] }
-               |  val_occ val_occs     { $1 : $2 }
 
-entity_occ     :: { OccName }
-               :  var_fs               { varOcc $1 }
-               |  data_fs              { tcOcc $1 }
+---------------------------------------------------
+var_fs          :: { EncodedFS }
+               : VARID                 { $1 }
+               | 'as'                  { SLIT("as") }
+               | 'qualified'           { SLIT("qualified") }
+               | 'hiding'              { SLIT("hiding") }
+               | 'forall'              { SLIT("forall") }
+               | 'foreign'             { SLIT("foreign") }
+               | 'export'              { SLIT("export") }
+               | 'label'               { SLIT("label") }
+               | 'dynamic'             { SLIT("dynamic") }
+               | 'unsafe'              { SLIT("unsafe") }
+               | 'with'                { SLIT("with") }
+               | 'ccall'               { SLIT("ccall") }
+               | 'stdcall'             { SLIT("stdcall") }
+
+var_occ                :: { OccName }
+               :  var_fs               { mkSysOccFS varName $1 }
 
 var_name       :: { RdrName }
-var_name       :  var_fs               { ifaceUnqualVar $1 }
+var_name       :  var_occ              { mkRdrUnqual $1 }
 
 qvar_name      :: { RdrName }
 qvar_name      :  var_name             { $1 }
-               |  QVARID               { ifaceQualVar $1 }
-               |  QVARSYM              { ifaceQualVar $1 }
+               |  QVARID               { mkIfaceOrig varName $1 }
+
+ipvar_name     :: { RdrName }
+               :  IPVARID              { mkRdrUnqual (mkSysOccFS varName (tailFS $1)) }
+
+qvar_names1    :: { [RdrName] }
+qvar_names1    : qvar_name             { [$1] }
+               | qvar_name qvar_names1 { $1 : $2 }
 
 var_names      :: { [RdrName] }
 var_names      :                       { [] }
@@ -432,86 +641,96 @@ var_names :                       { [] }
 var_names1     :: { [RdrName] }
 var_names1     : var_name var_names    { $1 : $2 }
 
-data_name      :: { RdrName }
-               :  CONID                { ifaceUnqualVar $1 }
-               |  CONSYM               { ifaceUnqualVar $1 }
-               |  '(' commas ')'       { ifaceUnqualVar (snd (mkTupNameStr $2)) }
-               |  '[' ']'              { ifaceUnqualVar SLIT("[]") }
+---------------------------------------------------
+
+data_occ       :: { OccName }
+               :  CONID                { mkSysOccFS dataName $1 }
 
 qdata_name     :: { RdrName }
-qdata_name     :  data_name            { $1 }
-               |  QCONID               { ifaceQualVar $1 }
-               |  QCONSYM              { ifaceQualVar $1 }
+               :  data_occ             { mkRdrUnqual $1 }
+               |  QCONID               { mkIfaceOrig dataName $1 }
                                
-qdata_names    :: { [RdrName] }
-qdata_names    :                               { [] }
-               | qdata_name qdata_names        { $1 : $2 }
+var_or_data_name :: { RdrName }
+                  : qvar_name          { $1 }
+                  | qdata_name         { $1 }
 
-tc_name                :: { RdrName }
-tc_name                :  CONID                { ifaceUnqualTC $1 }
-               |  CONSYM               { ifaceUnqualTC $1 }
-               |  '(' '->' ')'         { ifaceUnqualTC SLIT("->") }
-               |  '(' commas ')'       { ifaceUnqualTC (snd (mkTupNameStr $2)) }
-               |  '[' ']'              { ifaceUnqualTC SLIT("[]") }
+---------------------------------------------------
+tc_occ         :: { OccName }
+               :  CONID                { mkSysOccFS tcName $1 }
 
 qtc_name       :: { RdrName }
-qtc_name       : tc_name               { $1 }
-               | QCONID                { ifaceQualTC $1 }
-               | QCONSYM               { ifaceQualTC $1 }
+                : tc_occ               { mkRdrUnqual $1 }
+               | QCONID                { mkIfaceOrig tcName $1 }
+
+---------------------------------------------------
+qcls_name      :: { RdrName }
+               : CONID                 { mkRdrUnqual (mkSysOccFS clsName $1) }
+               | QCONID                { mkIfaceOrig clsName $1 }
 
+---------------------------------------------------
 tv_name                :: { RdrName }
-tv_name                :  VARID                { ifaceUnqualTv $1 }
-               |  VARSYM               { ifaceUnqualTv $1 {- Allow t2 as a tyvar -} }
+               :  var_fs               { mkRdrUnqual (mkSysOccFS tvName $1) }
+
+tv_bndr                :: { HsTyVarBndr RdrName }
+               :  tv_name '::' akind   { IfaceTyVar $1 $3 }
+               |  tv_name              { IfaceTyVar $1 liftedTypeKind }
 
-tv_bndr                :: { HsTyVar RdrName }
-tv_bndr                :  tv_name '::' akind   { IfaceTyVar $1 $3 }
-               |  tv_name              { IfaceTyVar $1 boxedTypeKind }
+tv_bndrs       :: { [HsTyVarBndr RdrName] }
+               : tv_bndrs1             { $1 }
+               | '[' tv_bndrs1 ']'     { $2 }  -- Backward compatibility
 
-tv_bndrs       :: { [HsTyVar RdrName] }
+tv_bndrs1      :: { [HsTyVarBndr RdrName] }
                :                       { [] }
-               | tv_bndr tv_bndrs      { $1 : $2 }
+               | tv_bndr tv_bndrs1     { $1 : $2 }
 
+---------------------------------------------------
+fds :: { [([RdrName], [RdrName])] }
+       : {- empty -}                   { [] }
+       | '|' fds1                      { reverse $2 }
+
+fds1 :: { [([RdrName], [RdrName])] }
+       : fds1 ',' fd                   { $3 : $1 }
+       | fd                            { [$1] }
+
+fd :: { ([RdrName], [RdrName]) }
+       : varids0 '->' varids0          { (reverse $1, reverse $3) }
+
+varids0        :: { [RdrName] }
+       : {- empty -}                   { [] }
+       | varids0 tv_name               { $2 : $1 }
+
+---------------------------------------------------
 kind           :: { Kind }
                : akind                 { $1 }
                | akind '->' kind       { mkArrowKind $1 $3 }
 
 akind          :: { Kind }
                : VARSYM                { if $1 == SLIT("*") then
-                                               boxedTypeKind
+                                               liftedTypeKind
                                          else if $1 == SLIT("?") then
                                                openTypeKind
-                                         else panic "ParseInterface: akind"
+                                         else if $1 == SLIT("\36") then
+                                                usageTypeKind  -- dollar
+                                          else panic "ParseInterface: akind"
                                        }
                | '(' kind ')'  { $2 }
 
 --------------------------------------------------------------------------
 
 id_info                :: { [HsIdInfo RdrName] }
-id_info                :                               { [] }
+               : id_info_item                  { [$1] }
                | id_info_item id_info          { $1 : $2 }
 
 id_info_item   :: { HsIdInfo RdrName }
-id_info_item   : '__A' arity_info              { HsArity $2 }
-               | strict_info                   { HsStrictness $1 }
-               | '__U' core_expr               { HsUnfold $1 (Just $2) }
-                | '__U'                        { HsUnfold $1 Nothing }
-                | '__P' spec_tvs
-                     atypes '=' core_expr       { HsSpecialise $2 $3 $5 }
+               : '__A' INTEGER                 { HsArity (fromInteger $2) }
+               | '__U' inline_prag core_expr   { HsUnfold $2 $3 }
+               | '__S'                         { HsStrictness $1 }
                | '__C'                         { HsNoCafRefs }
+               | '__P' qvar_name INTEGER       { HsWorker $2 (fromInteger $3) }
 
-
-spec_tvs       :: { [HsTyVar RdrName] }
-spec_tvs       : '[' tv_bndrs ']'              { $2 }
-       
-
-arity_info     :: { ArityInfo }
-arity_info     : INTEGER                       { exactArity (fromInteger $1) }
-
-strict_info    :: { HsStrictnessInfo RdrName }
-strict_info    : '__S' qvar_name '{' qdata_names '}'   
-                                       { HsStrictnessInfo $1 (Just ($2,$4)) }
-               | '__S' qvar_name       { HsStrictnessInfo $1 (Just ($2,[])) }
-               | '__S'                 { HsStrictnessInfo $1 Nothing }
+inline_prag     :: { InlinePragInfo }
+                :  {- empty -}                  { AlwaysActive }
+               | '[' INTEGER ']'               { ActiveAfter (fromInteger $2) }
 
 -------------------------------------------------------
 core_expr      :: { UfExpr RdrName }
@@ -524,20 +743,20 @@ core_expr : '\\' core_bndrs '->' core_expr        { foldr UfLam $4 $2 }
                | '__letrec' '{' rec_binds '}'          
                  'in' core_expr                        { UfLet (UfRec $3) $6 }
 
-               | con_or_primop '{' core_args '}'       { UfCon $1 $3 }
-                | '__litlit' STRING atype               { UfCon (UfLitLitCon $2 $3) [] }
+                | '__litlit' STRING atype               { UfLitLit $2 $3 }
 
-                | '__inline' core_expr               { UfNote UfInlineCall $2 }
-                | '__coerce' atype core_expr         { UfNote (UfCoerce $2) $3 }
-               | '__scc' core_expr                  { UfNote (UfSCC $1) $2  }
-               | fexpr                              { $1 }
+               | fexpr                                 { $1 }
 
 fexpr   :: { UfExpr RdrName }
 fexpr   : fexpr core_arg                               { UfApp $1 $2 }
+       | scc core_aexpr                                { UfNote (UfSCC $1) $2  }
+        | '__inline_me' core_aexpr                     { UfNote UfInlineMe $2 }
+        | '__inline_call' core_aexpr                   { UfNote UfInlineCall $2 }
+        | '__coerce' atype core_aexpr                  { UfNote (UfCoerce $2) $3 }
         | core_aexpr                                   { $1 }
 
 core_arg       :: { UfExpr RdrName }
-               : '__a' atype                                  { UfType $2 }
+               : '@' atype                                     { UfType $2 }
                 | core_aexpr                                    { $1 }
 
 core_args      :: { [UfExpr RdrName] }
@@ -546,84 +765,94 @@ core_args :: { [UfExpr RdrName] }
 
 core_aexpr      :: { UfExpr RdrName }              -- Atomic expressions
 core_aexpr      : qvar_name                                    { UfVar $1 }
-
                 | qdata_name                                    { UfVar $1 }
-                       -- This one means that e.g. "True" will parse as 
-                       -- (UfVar True_Id) rather than (UfCon True_Con []).
-                       -- No big deal; it'll be inlined in a jiffy.  I tried 
-                       -- parsing it to (Con con []) directly, but got bitten 
-                       -- when a real constructor Id showed up in an interface
-                       -- file.  As usual, a hack bites you in the end.
-                       -- If you want to get a UfCon, then use the
-                       -- curly-bracket notation (True {}).
-
-               | core_lit               { UfCon (UfLitCon $1) [] }
+
+               | core_lit               { UfLit $1 }
                | '(' core_expr ')'      { $2 }
-               | '('  ')'               { UfTuple (mkTupConRdrName 0) [] }
-               | '(' comma_exprs2 ')'   { UfTuple (mkTupConRdrName (length $2)) $2 }
-               | '(#' core_expr '#)'    { UfTuple (mkUbxTupConRdrName 1) [$2] }
-               | '(#' comma_exprs2 '#)' { UfTuple (mkUbxTupConRdrName (length $2)) $2 }
+
+               | '('  ')'               { UfTuple (mkHsTupCon dataName Boxed [])   [] }
+               | '(' comma_exprs2 ')'   { UfTuple (mkHsTupCon dataName Boxed $2)   $2 }
+               | '(#' comma_exprs0 '#)' { UfTuple (mkHsTupCon dataName Unboxed $2) $2 }
+
+                | '{' '__ccall' ccall_string type '}'       
+                           { let
+                                 (is_dyn, is_casm, may_gc) = $2
+
+                                target | is_dyn    = DynamicTarget
+                                       | is_casm   = CasmTarget $3
+                                       | otherwise = StaticTarget $3
+
+                                ccall = CCallSpec target CCallConv may_gc
+                            in
+                            UfFCall (CCall ccall) $4
+                          }
+
+
+comma_exprs0    :: { [UfExpr RdrName] }        -- Zero or more
+comma_exprs0   : {- empty -}                   { [ ] }
+               | core_expr                     { [ $1 ] }
+               | comma_exprs2                  { $1 }
 
 comma_exprs2   :: { [UfExpr RdrName] } -- Two or more
 comma_exprs2   : core_expr ',' core_expr                       { [$1,$3] }
                | core_expr ',' comma_exprs2                    { $1 : $3 }
 
-con_or_primop   :: { UfCon RdrName }
-con_or_primop   : qdata_name                    { UfDataCon $1 }
-                | qvar_name                    { UfPrimOp $1 }
-                | '__ccall' ccall_string      { let
-                                               (is_casm, may_gc) = $1
-                                               in
-                                               UfCCallOp $2 is_casm may_gc
-                                               }
-
 rec_binds      :: { [(UfBinder RdrName, UfExpr RdrName)] }
                :                                               { [] }
                | core_val_bndr '=' core_expr ';' rec_binds     { ($1,$3) : $5 }
 
 core_alts      :: { [UfAlt RdrName] }
-               : core_alt                                      { [$1] }
+               :                                               { [] }
                | core_alt ';' core_alts                        { $1 : $3 }
 
 core_alt        :: { UfAlt RdrName }
 core_alt       : core_pat '->' core_expr       { (fst $1, snd $1, $3) }
 
-core_pat       :: { (UfCon RdrName, [RdrName]) }
-core_pat       : core_lit                      { (UfLitCon  $1, []) }
-               | '__litlit' STRING atype       { (UfLitLitCon $2 $3, []) }
-               | qdata_name var_names          { (UfDataCon $1, $2) }
-               | '(' comma_var_names ')'       { (UfDataCon (mkTupConRdrName (length $2)), $2) }
-               | '(#' comma_var_names1 '#)'    { (UfDataCon (mkUbxTupConRdrName (length $2)), $2) }
+core_pat       :: { (UfConAlt RdrName, [RdrName]) }
+core_pat       : core_lit                      { (UfLitAlt  $1, []) }
+               | '__litlit' STRING atype       { (UfLitLitAlt $2 $3, []) }
+               | qdata_name core_pat_names     { (UfDataAlt $1, $2) }
+               | '('  ')'                      { (UfTupleAlt (mkHsTupCon dataName Boxed []),   []) }
+               | '(' comma_var_names1 ')'      { (UfTupleAlt (mkHsTupCon dataName Boxed $2),   $2) }
+               | '(#' comma_var_names1 '#)'    { (UfTupleAlt (mkHsTupCon dataName Unboxed $2), $2) }
                | '__DEFAULT'                   { (UfDefault, []) }
                | '(' core_pat ')'              { $2 }
 
-
-comma_var_names :: { [RdrName] }       -- Zero, or two or more
-comma_var_names :                                              { [] }
-               | var_name ',' comma_var_names1         { $1 : $3 }
-
+core_pat_names :: { [RdrName] }
+core_pat_names :                               { [] }
+               | core_pat_name core_pat_names  { $1 : $2 }
+
+-- Tyvar names and variable names live in different name spaces
+-- so they need to be signalled separately.  But we don't record 
+-- types or kinds in a pattern; we work that out from the type 
+-- of the case scrutinee
+core_pat_name  :: { RdrName }
+core_pat_name  : var_name                      { $1 }
+               | '@' tv_name                   { $2 }
+       
 comma_var_names1 :: { [RdrName] }      -- One or more
 comma_var_names1 : var_name                                    { [$1] }
                 | var_name ',' comma_var_names1                { $1 : $3 }
 
 core_lit       :: { Literal }
-core_lit       : INTEGER                       { mkMachInt_safe $1 }
+core_lit       : integer                       { mkMachInt $1 }
                | CHAR                          { MachChar $1 }
                | STRING                        { MachStr $1 }
-               | '__string' STRING             { NoRepStr $2 (panic "NoRepStr type") }
-               | RATIONAL                      { MachDouble $1 }
-               | '__float' RATIONAL            { MachFloat $2 }
-
-               | '__integer' INTEGER           { NoRepInteger  $2 (panic "NoRepInteger type") 
-                                                       -- The type checker will add the types
-                                               }
-
-               | '__rational' INTEGER INTEGER  { NoRepRational ($2 % $3) 
-                                                  (panic "NoRepRational type")
-                                                       -- The type checker will add the type
-                                               }
-
-               | '__addr' INTEGER              { MachAddr $2 }
+               | rational                      { MachDouble $1 }
+               | '__word' integer              { mkMachWord $2 }
+               | '__word64' integer            { mkMachWord64 $2 }
+               | '__int64' integer             { mkMachInt64 $2 }
+               | '__float' rational            { MachFloat $2 }
+               | '__addr' integer              { MachAddr $2 }
+               | '__label' STRING              { MachLabel $2 }
+
+integer                :: { Integer }
+               : INTEGER                       { $1 }
+               | '-' INTEGER                   { (-$2) }
+
+rational       :: { Rational }
+               : RATIONAL                      { $1 }
+               | '-' RATIONAL                  { (-$2) }
 
 core_bndr       :: { UfBinder RdrName }
 core_bndr       : core_val_bndr                                 { $1 }
@@ -637,19 +866,42 @@ core_val_bndr     :: { UfBinder RdrName }
 core_val_bndr  : var_name '::' atype                           { UfValBinder $1 $3 }
 
 core_tv_bndr   :: { UfBinder RdrName }
-core_tv_bndr   :  '__a' tv_name '::' akind             { UfTyBinder $2 $4 }
-               |  '__a' tv_name                        { UfTyBinder $2 boxedTypeKind }
+core_tv_bndr   :  '@' tv_name '::' akind               { UfTyBinder $2 $4 }
+               |  '@' tv_name                          { UfTyBinder $2 liftedTypeKind }
 
 ccall_string   :: { FAST_STRING }
                : STRING                                        { $1 }
+               | CLITLIT                                       { $1 }
                | VARID                                         { $1 }
                | CONID                                         { $1 }
 
+------------------------------------------------------------------------
+scc     :: { CostCentre }
+        :  '__sccC' '{' mod_name '}'                      { AllCafsCC $3 }
+        |  '__scc' '{' cc_name mod_name cc_dup cc_caf '}'
+                             { NormalCC { cc_name = $3, cc_mod = $4,
+                                          cc_is_dupd = $5, cc_is_caf = $6 } }
+
+cc_name :: { EncodedFS }
+        : CONID                 { $1 }
+        | var_fs                { $1 }
+  
+cc_dup  :: { IsDupdCC }
+cc_dup  :                       { OriginalCC }
+        | '!'                   { DupdCC }
+
+cc_caf  :: { IsCafCC }
+        :                       { NotCafCC }
+        | '__C'                 { CafCC }
+
 -------------------------------------------------------------------
 
 src_loc :: { SrcLoc }
-src_loc :                              {% getSrcLocIf }
+src_loc :                              {% getSrcLocP }
 
+-- Check the project version: this makes sure
+-- that the project version (e.g. 407) in the interface
+-- file is the same as that for the compiler that's reading it
 checkVersion :: { () }
           : {-empty-}                  {% checkVersion Nothing }
           | INTEGER                    {% checkVersion (Just (fromInteger $1)) }
@@ -658,10 +910,8 @@ checkVersion :: { () }
 
 --                     Haskell code 
 {
+happyError :: P a
+happyError buf PState{ loc = loc } = PFailed (ifaceParseErr buf loc)
 
-data IfaceStuff = PIface       ParsedIface
-               | PIdInfo       [HsIdInfo RdrName]
-               | PType         RdrNameHsType
-
-mkConDecl name (ex_tvs, ex_ctxt) details loc = ConDecl name ex_tvs ex_ctxt details loc
+mk_con_decl name (ex_tvs, ex_ctxt) details loc = mkConDecl name ex_tvs ex_ctxt details loc
 }