+ ppr (DefaultDecl tys src_loc)
+ = ptext SLIT("default") <+> parens (interpp'SP tys)
+\end{code}
+
+%************************************************************************
+%* *
+\subsection{Foreign function interface declaration}
+%* *
+%************************************************************************
+
+\begin{code}
+
+-- foreign declarations are distinguished as to whether they define or use a
+-- Haskell name
+--
+-- * the Boolean value indicates whether the pre-standard deprecated syntax
+-- has been used
+--
+data ForeignDecl name
+ = ForeignImport name (HsType name) ForeignImport Bool SrcLoc -- defines name
+ | ForeignExport name (HsType name) ForeignExport Bool SrcLoc -- uses name
+
+-- yield the Haskell name defined or used in a foreign declaration
+--
+foreignDeclName :: ForeignDecl name -> name
+foreignDeclName (ForeignImport n _ _ _ _) = n
+foreignDeclName (ForeignExport n _ _ _ _) = n
+
+-- specification of an imported external entity in dependence on the calling
+-- convention
+--
+data ForeignImport = -- import of a C entity
+ --
+ -- * the two strings specifying a header file or library
+ -- may be empty, which indicates the absence of a
+ -- header or object specification (both are not used
+ -- in the case of `CWrapper' and when `CFunction'
+ -- has a dynamic target)
+ --
+ -- * the calling convention is irrelevant for code
+ -- generation in the case of `CLabel', but is needed
+ -- for pretty printing
+ --
+ -- * `Safety' is irrelevant for `CLabel' and `CWrapper'
+ --
+ CImport CCallConv -- ccall or stdcall
+ Safety -- safe or unsafe
+ FastString -- name of C header
+ FastString -- name of library object
+ CImportSpec -- details of the C entity
+
+ -- import of a .NET function
+ --
+ | DNImport DNCallSpec
+
+-- details of an external C entity
+--
+data CImportSpec = CLabel CLabelString -- import address of a C label
+ | CFunction CCallTarget -- static or dynamic function
+ | CWrapper -- wrapper to expose closures
+ -- (former f.e.d.)
+
+-- specification of an externally exported entity in dependence on the calling
+-- convention
+--
+data ForeignExport = CExport CExportSpec -- contains the calling convention
+ | DNExport -- presently unused
+
+-- abstract type imported from .NET
+--
+data FoType = DNType -- In due course we'll add subtype stuff
+ deriving (Eq) -- Used for equality instance for TyClDecl
+
+
+-- pretty printing of foreign declarations
+--
+
+instance OutputableBndr name => Outputable (ForeignDecl name) where
+ ppr (ForeignImport n ty fimport _ _) =
+ ptext SLIT("foreign import") <+> ppr fimport <+>
+ ppr n <+> dcolon <+> ppr ty
+ ppr (ForeignExport n ty fexport _ _) =
+ ptext SLIT("foreign export") <+> ppr fexport <+>
+ ppr n <+> dcolon <+> ppr ty
+
+instance Outputable ForeignImport where
+ ppr (DNImport spec) =
+ ptext SLIT("dotnet") <+> ppr spec
+ ppr (CImport cconv safety header lib spec) =
+ ppr cconv <+> ppr safety <+>
+ char '"' <> pprCEntity header lib spec <> char '"'
+ where
+ pprCEntity header lib (CLabel lbl) =
+ ptext SLIT("static") <+> ftext header <+> char '&' <>
+ pprLib lib <> ppr lbl
+ pprCEntity header lib (CFunction (StaticTarget lbl)) =
+ ptext SLIT("static") <+> ftext header <+> char '&' <>
+ pprLib lib <> ppr lbl
+ pprCEntity header lib (CFunction (DynamicTarget)) =
+ ptext SLIT("dynamic")
+ pprCEntity header lib (CFunction (CasmTarget _)) =
+ panic "HsDecls.pprCEntity: malformed C function target"
+ pprCEntity _ _ (CWrapper) = ptext SLIT("wrapper")
+ --
+ pprLib lib | nullFastString lib = empty
+ | otherwise = char '[' <> ppr lib <> char ']'
+
+instance Outputable ForeignExport where
+ ppr (CExport (CExportStatic lbl cconv)) =
+ ppr cconv <+> char '"' <> ppr lbl <> char '"'
+ ppr (DNExport ) =
+ ptext SLIT("dotnet") <+> ptext SLIT("\"<unused>\"")
+
+instance Outputable FoType where
+ ppr DNType = ptext SLIT("type dotnet")
+\end{code}
+
+
+%************************************************************************
+%* *
+\subsection{Transformation rules}
+%* *
+%************************************************************************
+
+\begin{code}
+data RuleDecl name
+ = HsRule -- Source rule
+ RuleName -- Rule name
+ Activation
+ [RuleBndr name] -- Forall'd vars; after typechecking this includes tyvars
+ (HsExpr name) -- LHS
+ (HsExpr name) -- RHS
+ SrcLoc
+
+ | IfaceRule -- One that's come in from an interface file; pre-typecheck
+ RuleName
+ Activation
+ [UfBinder name] -- Tyvars and term vars
+ name -- Head of lhs
+ [UfExpr name] -- Args of LHS
+ (UfExpr name) -- Pre typecheck
+ SrcLoc
+
+ | IfaceRuleOut -- Post typecheck
+ name -- Head of LHS
+ CoreRule
+
+isSrcRule :: RuleDecl name -> Bool
+isSrcRule (HsRule _ _ _ _ _ _) = True
+isSrcRule other = False
+
+ifaceRuleDeclName :: RuleDecl name -> name
+ifaceRuleDeclName (IfaceRule _ _ _ n _ _ _) = n
+ifaceRuleDeclName (IfaceRuleOut n r) = n
+ifaceRuleDeclName (HsRule fs _ _ _ _ _) = pprPanic "ifaceRuleDeclName" (ppr fs)
+
+data RuleBndr name
+ = RuleBndr name
+ | RuleBndrSig name (HsType name)
+
+collectRuleBndrSigTys :: [RuleBndr name] -> [HsType name]
+collectRuleBndrSigTys bndrs = [ty | RuleBndrSig _ ty <- bndrs]
+
+instance (NamedThing name, Ord name) => Eq (RuleDecl name) where
+ -- Works for IfaceRules only; used when comparing interface file versions
+ (IfaceRule n1 a1 bs1 f1 es1 rhs1 _) == (IfaceRule n2 a2 bs2 f2 es2 rhs2 _)
+ = n1==n2 && f1 == f2 && a1==a2 &&
+ eq_ufBinders emptyEqHsEnv bs1 bs2 (\env ->
+ eqListBy (eq_ufExpr env) (rhs1:es1) (rhs2:es2))
+
+instance OutputableBndr name => Outputable (RuleDecl name) where
+ ppr (HsRule name act ns lhs rhs loc)
+ = sep [text "{-# RULES" <+> doubleQuotes (ftext name) <+> ppr act,
+ pp_forall, pprExpr lhs, equals <+> pprExpr rhs,
+ text "#-}" ]
+ where
+ pp_forall | null ns = empty
+ | otherwise = text "forall" <+> fsep (map ppr ns) <> dot
+
+ ppr (IfaceRule name act tpl_vars fn tpl_args rhs loc)
+ = hsep [ doubleQuotes (ftext name), ppr act,
+ ptext SLIT("__forall") <+> braces (interppSP tpl_vars),
+ ppr fn <+> sep (map (pprUfExpr parens) tpl_args),
+ ptext SLIT("=") <+> ppr rhs
+ ] <+> semi
+
+ ppr (IfaceRuleOut fn rule) = pprCoreRule (ppr fn) rule
+
+instance OutputableBndr name => Outputable (RuleBndr name) where
+ ppr (RuleBndr name) = ppr name
+ ppr (RuleBndrSig name ty) = ppr name <> dcolon <> ppr ty
+\end{code}
+
+
+%************************************************************************
+%* *
+\subsection[DeprecDecl]{Deprecations}
+%* *
+%************************************************************************
+
+We use exported entities for things to deprecate.
+
+\begin{code}
+data DeprecDecl name = Deprecation name DeprecTxt SrcLoc
+
+type DeprecTxt = FastString -- reason/explanation for deprecation
+
+instance OutputableBndr name => Outputable (DeprecDecl name) where
+ ppr (Deprecation thing txt _)
+ = hsep [text "{-# DEPRECATED", ppr thing, doubleQuotes (ppr txt), text "#-}"]
+\end{code}
+
+
+%************************************************************************
+%* *
+ External-core declarations
+%* *
+%************************************************************************
+
+\begin{code}
+data CoreDecl name -- a Core value binding (from 'external Core' input)
+ = CoreDecl name
+ (HsType name)
+ (UfExpr name)
+ SrcLoc
+
+instance OutputableBndr name => Outputable (CoreDecl name) where
+ ppr (CoreDecl var ty rhs loc)
+ = getPprStyle $ \ sty ->
+ hsep [ pprHsVar var, dcolon, ppr ty, ppr rhs ]