hs-bindgen-1.0.0.0: src-internal/HsBindgen/Frontend/Pass/TypecheckMacros.hs
module HsBindgen.Frontend.Pass.TypecheckMacros (
typecheckMacros
) where
import Data.Foldable qualified as Foldable
import Data.Map qualified as Map
import HsBindgen.Frontend.Analysis.DeclIndex qualified as DeclIndex
import HsBindgen.Frontend.DeclMeta
import HsBindgen.Frontend.LanguageC qualified as LanC
import HsBindgen.Frontend.Pass.ConstructTranslationUnit.IsPass
import HsBindgen.Frontend.Pass.TypecheckMacros.IsPass
import HsBindgen.Frontend.Pass.TypecheckMacros.KnownTypes
import HsBindgen.Frontend.Pass.TypecheckMacros.Typecheck
import HsBindgen.Frontend.TranslationUnit qualified as C
import HsBindgen.Imports
import HsBindgen.IR.C qualified as C
import HsBindgen.Macro.Interface qualified as Macro
import HsBindgen.Macro.Type qualified as Macro
type In = ConstructTranslationUnit
type Out = TypecheckMacros
-- | We perform two traversals:
--
-- Traversal 1: collect known types
--
-- Traversal 2: typecheck macros
--
-- Return the updated translation unit together with the 'LanC.ReparseEnv' that
-- 'reparseMacroExpansions' uses to reparse declarations.
--
-- Register macro typecheck failures in @DeclMeta@.
typecheckMacros ::
Macro.HasTypes l
=> Macro.Lang l
-> C.TranslationUnit l In
-> ( C.TranslationUnit l Out
, Map LanC.CName (C.Type TypecheckMacros)
, Set LanC.CName
)
typecheckMacros macroLang unit =
let knownTypes =
collectKnownTypes unit.decls
(typecheckedDecls, knownMacroTypes, failedMacros) =
typecheckDecls macroLang unit.decls
in ( reconstructAfterTypecheck unit failedMacros typecheckedDecls
, Map.fromList [
(n, v)
| (declId, v) <- Map.toList knownTypes
, Just n <- [C.renderNamedDeclId declId]
]
, knownMacroTypes
)
reconstructAfterTypecheck ::
C.TranslationUnit l In
-> [FailedMacro]
-> [C.Decl l Out]
-> C.TranslationUnit l Out
reconstructAfterTypecheck unit failedMacros decls =
C.TranslationUnit{
decls = decls
, includeGraph = unit.includeGraph
, meta = unit.meta{
declIndex =
Foldable.foldl'
DeclIndex.registerMacroTypecheckFailure
unit.meta.declIndex
failedMacros
}
}