{-# LANGUAGE CPP #-}

module GHC.Exts.Heap.FFIClosures (module Reexport) where

-- NOTE [hsc and CPP workaround]
--
-- # Problem
--
-- Often, .hsc files are used to get the correct offsets of C struct fields.
-- Those structs may be affected by CPP directives e.g. profiled vs not profiled
-- closure headers is affected by the PROFILED cpp define. Since we are building
-- multiple variants of the RTS, we must support all possible offsets e.g. by
-- running hsc2hs with cpp defines corresponding to each RTS flavour. The
-- problem is that GHC's build system runs hsc2hs *only once* per .hsc file
-- without properly setting cpp defines. This results in the same (probably
-- incorrect) offsets into our C structs.
--
--
-- # Workaround
--
-- To work around this issue, we create multiple .hsc files each manually
-- defining thir cpp defines (see e.g. FFIClosures_ProfilingDisabled.hsc and
-- FFIClosures_ProfilingEnabled.hsc). Then we rely on cpp defines working
-- correctly in .hs files and use CPP to switch on which .hsc module to
-- re-export (see below). In each case we import the desired .hsc module as
-- `Reexport` and we import `()` (i.e. nothing) from all other .hsc variants
-- just so that the build system sees all .hsc file as dependencies.
--
--
-- # Future Work
--
-- * Duplication of the code in the .hsc files could be reduced simply by
--   placing the code in a single .hsc.in file and `#include`ing it from each
--   .hsc file. The .hsc files would only be responsible for setting the correct
--   cpp defines. This currently doesn't work as hadrian doesn't know to copy
--   the .hsc.in file to the build directory.
-- * The correct solution would be for the build system to run `hsc2hs` with the
--   correct cpp defines once per RTS flavour.
--

#if defined(PROFILING)
import GHC.Exts.Heap.FFIClosures_ProfilingEnabled as Reexport
import GHC.Exts.Heap.FFIClosures_ProfilingDisabled ()
#else
import GHC.Exts.Heap.FFIClosures_ProfilingDisabled as Reexport
import GHC.Exts.Heap.FFIClosures_ProfilingEnabled ()
#endif