    {-# LANGUAGE CPP #-}

    -- | @unsafe@ variants of the "Language.C.Inline" quasi-quoters, to call the C code
    -- unsafely in the sense of
    -- <https://www.haskell.org/onlinereport/haskell2010/haskellch8.html#x15-1590008.4.3>.
    -- In GHC, unsafe foreign calls are faster than safe foreign calls, but the user
    -- must guarantee the control flow will never enter Haskell code (via a callback
    -- or otherwise) before the call is done.
    --
    -- This module is intended to be imported qualified:
    --
    -- @
    -- import qualified "Language.C.Inline.Unsafe" as CU
    -- @

    module Language.C.Inline.Unsafe
      ( exp
      , pure
      , block
      ) where

    #if __GLASGOW_HASKELL__ < 710
    import           Prelude hiding (exp)
    #else
    import           Prelude hiding (exp, pure)
    #endif

    import qualified Language.Haskell.TH.Quote as TH
    import qualified Language.Haskell.TH.Syntax as TH

    import           Language.C.Inline.Context
    import           Language.C.Inline.Internal

    -- | C expressions.
    exp :: TH.QuasiQuoter
    exp :: QuasiQuoter
    exp = Purity
    -> (Loc
        -> TypeQ
        -> Type CIdentifier
        -> [(CIdentifier, Type CIdentifier)]
        -> String
        -> ExpQ)
    -> QuasiQuoter
    genericQuote Purity
    IO ((Loc
      -> TypeQ
      -> Type CIdentifier
      -> [(CIdentifier, Type CIdentifier)]
      -> String
      -> ExpQ)
     -> QuasiQuoter)
    -> (Loc
        -> TypeQ
        -> Type CIdentifier
        -> [(CIdentifier, Type CIdentifier)]
        -> String
        -> ExpQ)
    -> QuasiQuoter
    forall a b. (a -> b) -> a -> b
    $ Safety
    -> Loc
    -> TypeQ
    -> Type CIdentifier
    -> [(CIdentifier, Type CIdentifier)]
    -> String
    -> ExpQ
    inlineExp Safety
    TH.Unsafe

    -- | Variant of 'exp', for use with expressions known to have no side effects.
    --
    -- __BEWARE__: Use this function with caution, only when you know what you are
    -- doing. If an expression does in fact have side-effects, then indiscriminate
    -- use of 'pure' may endanger referential transparency, and in principle even
    -- type safety. Also note that the function may run more than once and that it
    -- may run in parallel with itself, given that
    -- 'System.IO.Unsafe.unsafeDupablePerformIO' is used to call the provided C
    -- code [to ensure good performance using the threaded
    -- runtime](https://github.com/fpco/inline-c/issues/115).  Please refer to the
    -- documentation for 'System.IO.Unsafe.unsafeDupablePerformIO' for more
    -- details.
    pure :: TH.QuasiQuoter
    pure :: QuasiQuoter
    pure = Purity
    -> (Loc
        -> TypeQ
        -> Type CIdentifier
        -> [(CIdentifier, Type CIdentifier)]
        -> String
        -> ExpQ)
    -> QuasiQuoter
    genericQuote Purity
    Pure ((Loc
      -> TypeQ
      -> Type CIdentifier
      -> [(CIdentifier, Type CIdentifier)]
      -> String
      -> ExpQ)
     -> QuasiQuoter)
    -> (Loc
        -> TypeQ
        -> Type CIdentifier
        -> [(CIdentifier, Type CIdentifier)]
        -> String
        -> ExpQ)
    -> QuasiQuoter
    forall a b. (a -> b) -> a -> b
    $ Safety
    -> Loc
    -> TypeQ
    -> Type CIdentifier
    -> [(CIdentifier, Type CIdentifier)]
    -> String
    -> ExpQ
    inlineExp Safety
    TH.Unsafe

    -- | C code blocks (i.e. statements).
    block :: TH.QuasiQuoter
    block :: QuasiQuoter
    block = Purity
    -> (Loc
        -> TypeQ
        -> Type CIdentifier
        -> [(CIdentifier, Type CIdentifier)]
        -> String
        -> ExpQ)
    -> QuasiQuoter
    genericQuote Purity
    IO ((Loc
      -> TypeQ
      -> Type CIdentifier
      -> [(CIdentifier, Type CIdentifier)]
      -> String
      -> ExpQ)
     -> QuasiQuoter)
    -> (Loc
        -> TypeQ
        -> Type CIdentifier
        -> [(CIdentifier, Type CIdentifier)]
        -> String
        -> ExpQ)
    -> QuasiQuoter
    forall a b. (a -> b) -> a -> b
    $ Safety
    -> Bool
    -> Maybe String
    -> Loc
    -> TypeQ
    -> Type CIdentifier
    -> [(CIdentifier, Type CIdentifier)]
    -> String
    -> ExpQ
    inlineItems Safety
    TH.Unsafe Bool
    False Maybe String
    forall a. Maybe a
    Nothing