packages feed

llvm-hs (empty) → 4.0.0.0

raw patch · 162 files changed

+14931/−0 lines, 162 filesdep +QuickCheckdep +arraydep +basebuild-type:Customsetup-changed

Dependencies added: QuickCheck, array, base, bytestring, containers, llvm-hs, llvm-hs-pure, mtl, parsec, pretty-show, semigroups, tasty, tasty-hunit, tasty-quickcheck, template-haskell, temporary, transformers, transformers-compat, utf8-string

Files

+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2013, Benjamin S. Scarlet and Google Inc.+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are+met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Benjamin S. Scarlet nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,189 @@+{-# LANGUAGE FlexibleInstances #-}+import Control.Exception (SomeException, try)+import Control.Monad+import Data.Functor+import Data.Maybe+import Data.List (isPrefixOf, (\\), intercalate, stripPrefix, find)+import Data.Map (Map)+import qualified Data.Map as Map+import Data.Monoid+import Data.Char+import Distribution.Simple+import Distribution.Simple.PreProcess+import Distribution.Simple.Program+import Distribution.Simple.Setup hiding (Flag)+import Distribution.Simple.LocalBuildInfo+import Distribution.PackageDescription+import Distribution.Version+import System.Environment+import Distribution.System++-- define these selectively in C files (we are _not_ using HsFFI.h),+-- rather than universally in the ccOptions, because HsFFI.h currently defines them+-- without checking they're already defined and so causes warnings.+uncheckedHsFFIDefines = ["__STDC_LIMIT_MACROS"]++llvmVersion = Version [4,0] []++llvmConfigNames = [+  "llvm-config-" ++ (intercalate "." . map show . versionBranch $ llvmVersion),+  "llvm-config"+ ]++findJustBy :: Monad m => (a -> m (Maybe b)) -> [a] -> m (Maybe b)+findJustBy f (x:xs) = do+  x' <- f x+  case x' of+    Nothing -> findJustBy f xs+    j -> return j+findJustBy _ [] = return Nothing++class ProgramSearch a where+  programSearch :: (String -> a) -> a++-- this instance is used before Cabal-1.18.0, when programFindLocation took one argument+instance Monad m => ProgramSearch (v -> m (Maybe b)) where+  programSearch checkName = \v -> findJustBy (\n -> checkName n v) llvmConfigNames++-- this instance is used for and after Cabal-1.18.0, when programFindLocation took two arguments+instance Monad m => ProgramSearch (v -> p -> m (Maybe b)) where+  programSearch checkName = \v p -> findJustBy (\n -> checkName n v p) llvmConfigNames++class OldHookable hook where+  preHookOld :: (PackageDescription -> LocalBuildInfo -> UserHooks -> TestFlags -> IO ()) -> hook -> hook++-- this instance is used before Cabal-1.22.0.0, when testHook took four arguments+instance OldHookable (PackageDescription -> LocalBuildInfo -> UserHooks -> TestFlags -> IO ()) where+  preHookOld f hook = \packageDescription localBuildInfo userHooks testFlags -> do+    f packageDescription localBuildInfo userHooks testFlags+    hook packageDescription localBuildInfo userHooks testFlags++-- this instance is used for and after Cabal-1.22.0.0, when testHook took four five arguments+instance OldHookable (Args -> PackageDescription -> LocalBuildInfo -> UserHooks -> TestFlags -> IO ()) where+  preHookOld f hook = \args packageDescription localBuildInfo userHooks testFlags -> do+    f packageDescription localBuildInfo userHooks testFlags+    hook args packageDescription localBuildInfo userHooks testFlags++llvmProgram :: Program+llvmProgram = (simpleProgram "llvm-config") {+  programFindLocation = programSearch (programFindLocation . simpleProgram),+  programFindVersion =+    let+      stripSuffix suf str = let r = reverse in liftM r (stripPrefix (r suf) (r str))+      svnToTag v = maybe v (++"-svn") (stripSuffix "svn" v)+      trim = dropWhile isSpace . reverse . dropWhile isSpace . reverse+    in+      \v p -> findProgramVersion "--version" (svnToTag . trim) v p+ }++getLLVMConfig :: ConfigFlags -> IO ([String] -> IO String)+getLLVMConfig configFlags = do+  let verbosity = fromFlag $ configVerbosity configFlags+  (program, _, _) <- requireProgramVersion verbosity llvmProgram+                     (withinVersion llvmVersion)+                     (configPrograms configFlags)+  return $ getProgramOutput verbosity program++addToLdLibraryPath :: String -> IO ()+addToLdLibraryPath path = do+  let (ldLibraryPathVar, ldLibraryPathSep) =+        case buildOS of+          OSX -> ("DYLD_LIBRARY_PATH",":")+          _ -> ("LD_LIBRARY_PATH",":")+  v <- try $ getEnv ldLibraryPathVar :: IO (Either SomeException String)+  setEnv ldLibraryPathVar (path ++ either (const "") (ldLibraryPathSep ++) v)++addLLVMToLdLibraryPath :: ConfigFlags -> IO ()+addLLVMToLdLibraryPath configFlags = do+  llvmConfig <- getLLVMConfig configFlags+  [libDir] <- liftM lines $ llvmConfig ["--libdir"]+  addToLdLibraryPath libDir++-- | These flags are not relevant for us and dropping them allows+-- linking against LLVM build with Clang using GCC+ignoredCxxFlags :: [String]+ignoredCxxFlags =+  ["-Wcovered-switch-default", "-fcolor-diagnostics"] ++ map ("-D" ++) uncheckedHsFFIDefines++ignoredCFlags :: [String]+ignoredCFlags = ["-Wcovered-switch-default", "-Wdelete-non-virtual-dtor", "-fcolor-diagnostics"]++-- | Header directories are added separately to configExtraIncludeDirs+isIncludeFlag :: String -> Bool+isIncludeFlag flag = "-I" `isPrefixOf` flag++isIgnoredCFlag :: String -> Bool+isIgnoredCFlag flag = flag `elem` ignoredCFlags || isIncludeFlag flag++isIgnoredCxxFlag :: String -> Bool+isIgnoredCxxFlag flag = flag `elem` ignoredCxxFlags || isIncludeFlag flag++main = do+  let origUserHooks = simpleUserHooks++  defaultMainWithHooks origUserHooks {+    hookedPrograms = [ llvmProgram ],++    confHook = \(genericPackageDescription, hookedBuildInfo) configFlags -> do+      llvmConfig <- getLLVMConfig configFlags+      llvmCxxFlags <- do+        rawLlvmCxxFlags <- llvmConfig ["--cxxflags"]+        return . filter (not . isIgnoredCxxFlag) $ words rawLlvmCxxFlags+      let stdLib = maybe "stdc++"+                         (drop (length stdlibPrefix))+                         (find (isPrefixOf stdlibPrefix) llvmCxxFlags)+            where stdlibPrefix = "-stdlib=lib"+      includeDirs <- liftM lines $ llvmConfig ["--includedir"]+      libDirs@[libDir] <- liftM lines $ llvmConfig ["--libdir"]+      [llvmVersion] <- liftM lines $ llvmConfig ["--version"]+      let getLibs = liftM (map (fromJust . stripPrefix "-l") . words) . llvmConfig+          flags    = configConfigurationsFlags configFlags+          linkFlag = case lookup (FlagName "shared-llvm") flags of+                       Nothing     -> "--link-static"+                       Just shared -> if shared then "--link-shared" else "--link-static"+      libs       <- getLibs ["--libs", linkFlag]+      systemLibs <- getLibs ["--system-libs"]++      let genericPackageDescription' = genericPackageDescription {+            condLibrary = do+              libraryCondTree <- condLibrary genericPackageDescription+              return libraryCondTree {+                condTreeData = condTreeData libraryCondTree <> mempty {+                    libBuildInfo =+                      mempty {+                        ccOptions = llvmCxxFlags,+                        extraLibs = stdLib : libs ++ systemLibs+                      }+                  }+              }+           }+          configFlags' = configFlags {+            configExtraLibDirs = libDirs ++ configExtraLibDirs configFlags,+            configExtraIncludeDirs = includeDirs ++ configExtraIncludeDirs configFlags+           }+      addLLVMToLdLibraryPath configFlags'+      confHook simpleUserHooks (genericPackageDescription', hookedBuildInfo) configFlags',++    hookedPreProcessors =+      let origHookedPreprocessors = hookedPreProcessors origUserHooks+          newHsc buildInfo localBuildInfo =+              PreProcessor {+                  platformIndependent = platformIndependent (origHsc buildInfo localBuildInfo),+                  runPreProcessor = \inFiles outFiles verbosity -> do+                      llvmConfig <- getLLVMConfig (configFlags localBuildInfo)+                      llvmCFlags <- do+                          rawLlvmCFlags <- llvmConfig ["--cflags"]+                          return . filter (not . isIgnoredCFlag) $ words rawLlvmCFlags+                      let buildInfo' = buildInfo { ccOptions = "-Wno-variadic-macros" : llvmCFlags }+                      runPreProcessor (origHsc buildInfo' localBuildInfo) inFiles outFiles verbosity+              }+              where origHsc = fromMaybe ppHsc2hs (lookup "hsc" origHookedPreprocessors)+      in [("hsc", newHsc)] ++ origHookedPreprocessors,++    buildHook = \packageDescription localBuildInfo userHooks buildFlags -> do+          addLLVMToLdLibraryPath (configFlags localBuildInfo)+          buildHook origUserHooks packageDescription localBuildInfo userHooks buildFlags,++    testHook = preHookOld (\_ localBuildInfo _ _ -> addLLVMToLdLibraryPath (configFlags localBuildInfo))+               (testHook origUserHooks)+   }
+ llvm-hs.cabal view
@@ -0,0 +1,273 @@+name: llvm-hs+version: 4.0.0.0+license: BSD3+license-file: LICENSE+author: Anthony Cowley, Stephen Diehl, Moritz Kiefer <moritz.kiefer@purelyfunctional.org>, Benjamin S. Scarlet+maintainer: Anthony Cowley, Stephen Diehl, Moritz Kiefer <moritz.kiefer@purelyfunctional.org>+copyright: (c) 2013 Benjamin S. Scarlet and Google Inc.+homepage: http://github.com/llvm-hs/llvm-hs/+bug-reports: http://github.com/llvm-hs/llvm-hs/issues+build-type: Custom+stability: experimental+cabal-version: >= 1.8+category: Compilers/Interpreters, Code Generation+synopsis: General purpose LLVM bindings+description:+  llvm-hs is a set of Haskell bindings for LLVM <http://llvm.org/>. Unlike other current Haskell bindings,+  it uses an ADT to represent LLVM IR (<http://llvm.org/docs/LangRef.html>), and so offers two advantages: it+  handles almost all of the stateful complexities of using the LLVM API to build IR; and it supports moving IR not+  only from Haskell into LLVM C++ objects, but the other direction - from LLVM C++ into Haskell.+extra-source-files:+  src/LLVM/Internal/FFI/Analysis.h+  src/LLVM/Internal/FFI/Attribute.h+  src/LLVM/Internal/FFI/AttributeC.hpp+  src/LLVM/Internal/FFI/BinaryOperator.h+  src/LLVM/Internal/FFI/CallingConvention.h+  src/LLVM/Internal/FFI/Constant.h+  src/LLVM/Internal/FFI/GlobalValue.h+  src/LLVM/Internal/FFI/InlineAssembly.h+  src/LLVM/Internal/FFI/Instruction.h+  src/LLVM/Internal/FFI/LibFunc.h+  src/LLVM/Internal/FFI/Metadata.hpp+  src/LLVM/Internal/FFI/OrcJIT.h+  src/LLVM/Internal/FFI/SMDiagnostic.h+  src/LLVM/Internal/FFI/Target.h+  src/LLVM/Internal/FFI/Target.hpp+  src/LLVM/Internal/FFI/Type.h+  src/LLVM/Internal/FFI/Value.h+tested-with: GHC == 7.8.4, GHC == 7.10.3, GHC == 8.0.2++source-repository head+  type: git+  location: git://github.com/llvm-hs/llvm-hs.git+  branch: llvm-4++flag shared-llvm+  description: link against llvm shared rather than static library+  default: True++flag debug+  description: compile C(++) shims with debug info for ease of troubleshooting+  default: False++flag semigroups+  description: Add semigroups to build-depends for Data.List.NonEmpty. This will be selected automatically by cabal.+  default: False++custom-setup+  setup-depends: base+               , Cabal+               , containers++library+  build-tools: llvm-config+  ghc-options: -Wall -fno-warn-name-shadowing -fno-warn-orphans -fno-warn-incomplete-patterns -fno-warn-missing-signatures -fno-warn-unused-matches -fno-warn-unused-do-bind -fno-warn-type-defaults+  if flag(semigroups)+    build-depends:+      base >= 4.7 && < 4.9,+      semigroups >= 0.18 && < 0.19+  else+    build-depends:+      base >= 4.9 && < 5+  build-depends:+    utf8-string >= 0.3.7,+    bytestring >= 0.9.1.10,+    transformers >= 0.3 && < 0.6,+    transformers-compat >= 0.4,+    mtl >= 2.1.3,+    template-haskell >= 2.5.0.0,+    containers >= 0.4.2.1,+    parsec >= 3.1.3,+    array >= 0.4.0.0,+    llvm-hs-pure == 4.0.0.0+  hs-source-dirs: src+  extensions:+    NoImplicitPrelude+    TupleSections+    DeriveDataTypeable+    EmptyDataDecls+    FlexibleContexts+    FlexibleInstances+    StandaloneDeriving+    ConstraintKinds+  exposed-modules:+    LLVM+    LLVM.Analysis+    LLVM.CodeGenOpt+    LLVM.CodeModel+    LLVM.CommandLine+    LLVM.Context+    LLVM.Diagnostic+    LLVM.ExecutionEngine+    LLVM.Internal.Analysis+    LLVM.Internal.Atomicity+    LLVM.Internal.Attribute+    LLVM.Internal.BasicBlock+    LLVM.Internal.CallingConvention+    LLVM.Internal.Coding+    LLVM.Internal.CommandLine+    LLVM.Internal.Constant+    LLVM.Internal.Context+    LLVM.Internal.DataLayout+    LLVM.Internal.DecodeAST+    LLVM.Internal.Diagnostic+    LLVM.Internal.EncodeAST+    LLVM.Internal.ExecutionEngine+    LLVM.Internal.FastMathFlags+    LLVM.Internal.FloatingPointPredicate+    LLVM.Internal.Function+    LLVM.Internal.Global+    LLVM.Internal.Inject+    LLVM.Internal.InlineAssembly+    LLVM.Internal.Instruction+    LLVM.Internal.InstructionDefs+    LLVM.Internal.IntegerPredicate+    LLVM.Internal.LibraryFunction+    LLVM.Internal.MemoryBuffer+    LLVM.Internal.Metadata+    LLVM.Internal.Module+    LLVM.Internal.OrcJIT+    LLVM.Internal.OrcJIT.CompileOnDemandLayer+    LLVM.Internal.OrcJIT.IRCompileLayer+    LLVM.Internal.Operand+    LLVM.Internal.PassManager+    LLVM.Internal.RawOStream+    LLVM.Internal.RMWOperation+    LLVM.Internal.String+    LLVM.Internal.TailCallKind+    LLVM.Internal.Target+    LLVM.Internal.Threading+    LLVM.Internal.Type+    LLVM.Internal.Value+    LLVM.Internal.FFI.Analysis+    LLVM.Internal.FFI.Attribute+    LLVM.Internal.FFI.Assembly+    LLVM.Internal.FFI.BasicBlock+    LLVM.Internal.FFI.BinaryOperator+    LLVM.Internal.FFI.Bitcode+    LLVM.Internal.FFI.Builder+    LLVM.Internal.FFI.ByteRangeCallback+    LLVM.Internal.FFI.Cleanup+    LLVM.Internal.FFI.CommandLine+    LLVM.Internal.FFI.Constant+    LLVM.Internal.FFI.Context+    LLVM.Internal.FFI.DataLayout+    LLVM.Internal.FFI.ExecutionEngine+    LLVM.Internal.FFI.Function+    LLVM.Internal.FFI.GlobalAlias+    LLVM.Internal.FFI.GlobalValue+    LLVM.Internal.FFI.GlobalVariable+    LLVM.Internal.FFI.InlineAssembly+    LLVM.Internal.FFI.Instruction+    LLVM.Internal.FFI.InstructionDefs+    LLVM.Internal.FFI.Iterate+    LLVM.Internal.FFI.LLVMCTypes+    LLVM.Internal.FFI.MemoryBuffer+    LLVM.Internal.FFI.Metadata+    LLVM.Internal.FFI.Module+    LLVM.Internal.FFI.OrcJIT+    LLVM.Internal.FFI.OrcJIT.CompileOnDemandLayer+    LLVM.Internal.FFI.OrcJIT.IRCompileLayer+    LLVM.Internal.FFI.PassManager+    LLVM.Internal.FFI.PtrHierarchy+    LLVM.Internal.FFI.RawOStream+    LLVM.Internal.FFI.SMDiagnostic+    LLVM.Internal.FFI.Target+    LLVM.Internal.FFI.Threading+    LLVM.Internal.FFI.Transforms+    LLVM.Internal.FFI.Type+    LLVM.Internal.FFI.User+    LLVM.Internal.FFI.Value+    LLVM.Module+    LLVM.OrcJIT+    LLVM.OrcJIT.CompileOnDemandLayer+    LLVM.OrcJIT.IRCompileLayer+    LLVM.PassManager+    LLVM.Relocation+    LLVM.Target+    LLVM.Target.LibraryFunction+    LLVM.Target.Options+    LLVM.Threading+    LLVM.Transforms++  other-modules:+    Control.Monad.AnyCont+    Control.Monad.AnyCont.Class+    Control.Monad.Trans.AnyCont++  include-dirs: src+  c-sources:+    src/LLVM/Internal/FFI/AssemblyC.cpp+    src/LLVM/Internal/FFI/AttributeC.cpp+    src/LLVM/Internal/FFI/BitcodeC.cpp+    src/LLVM/Internal/FFI/BuilderC.cpp+    src/LLVM/Internal/FFI/CallingConventionC.cpp+    src/LLVM/Internal/FFI/ConstantC.cpp+    src/LLVM/Internal/FFI/CommandLineC.cpp+    src/LLVM/Internal/FFI/ExecutionEngineC.cpp+    src/LLVM/Internal/FFI/FunctionC.cpp+    src/LLVM/Internal/FFI/GlobalAliasC.cpp+    src/LLVM/Internal/FFI/GlobalValueC.cpp+    src/LLVM/Internal/FFI/InlineAssemblyC.cpp+    src/LLVM/Internal/FFI/InstructionC.cpp+    src/LLVM/Internal/FFI/MetadataC.cpp+    src/LLVM/Internal/FFI/ModuleC.cpp+    src/LLVM/Internal/FFI/OrcJITC.cpp+    src/LLVM/Internal/FFI/RawOStreamC.cpp+    src/LLVM/Internal/FFI/PassManagerC.cpp+    src/LLVM/Internal/FFI/SMDiagnosticC.cpp+    src/LLVM/Internal/FFI/TargetC.cpp+    src/LLVM/Internal/FFI/TypeC.cpp+    src/LLVM/Internal/FFI/ValueC.cpp++  if flag(debug)+    cc-options: -g++test-suite test+  type: exitcode-stdio-1.0+  if flag(semigroups)+    build-depends:+      base >= 4.7 && < 4.9,+      semigroups >= 0.18 && < 0.19+  else+    build-depends:+      base >= 4.9 && < 5+  build-depends:+    bytestring >= 0.10 && < 0.11,+    tasty >= 0.11,+    tasty-hunit >= 0.9,+    tasty-quickcheck >= 0.8,+    QuickCheck >= 2.5.1.1,+    llvm-hs,+    llvm-hs-pure == 4.0.0.0,+    containers >= 0.4.2.1,+    mtl >= 2.1,+    transformers >= 0.3.0.0,+    transformers-compat,+    temporary >= 1.2 && < 1.3,+    pretty-show >= 1.6 && < 1.7+  hs-source-dirs: test+  extensions:+    TupleSections+    FlexibleInstances+    FlexibleContexts+  main-is: Test.hs+  other-modules:+    LLVM.Test.Analysis+    LLVM.Test.CallingConvention+    LLVM.Test.Constants+    LLVM.Test.DataLayout+    LLVM.Test.ExecutionEngine+    LLVM.Test.Global+    LLVM.Test.InlineAssembly+    LLVM.Test.Instructions+    LLVM.Test.Instrumentation+    LLVM.Test.Linking+    LLVM.Test.Metadata+    LLVM.Test.Module+    LLVM.Test.ObjectCode+    LLVM.Test.OrcJIT+    LLVM.Test.Optimization+    LLVM.Test.Support+    LLVM.Test.Target+    LLVM.Test.Tests
+ src/Control/Monad/AnyCont.hs view
@@ -0,0 +1,30 @@+{-# LANGUAGE+  MultiParamTypeClasses,+  UndecidableInstances+  #-}+module Control.Monad.AnyCont (+    MonadAnyCont(..),+    ScopeAnyCont(..),+    AnyContT(..),+    MonadTransAnyCont(..),+    runAnyContT,+    withAnyContT,+    mapAnyContT+  ) where++import Prelude++import Control.Monad.Trans.AnyCont+import Control.Monad.AnyCont.Class+import Control.Monad.Trans.Class+import Control.Monad.State.Class+import Control.Monad.Error.Class++instance MonadState s m => MonadState s (AnyContT m) where+  get = lift get+  put = lift . put+  state = lift . state++instance MonadError e m => MonadError e (AnyContT m) where+  throwError = lift . throwError+  x `catchError` h = anyContT $ \f -> (runAnyContT x f) `catchError` (\e -> runAnyContT (h e) f)
+ src/Control/Monad/AnyCont/Class.hs view
@@ -0,0 +1,54 @@+{-# LANGUAGE+  RankNTypes,+  MultiParamTypeClasses,+  UndecidableInstances+  #-}+module Control.Monad.AnyCont.Class where++import Prelude++import Control.Monad.Trans.Class+import Control.Monad.Trans.AnyCont (AnyContT)+import qualified Control.Monad.Trans.AnyCont as AnyCont+import Control.Monad.Trans.Except as Except+import Control.Monad.Trans.State as State++class ScopeAnyCont m where+  scopeAnyCont :: m a -> m a++class MonadAnyCont b m where+  anyContToM :: (forall r . (a -> b r) -> b r) -> m a+++instance MonadTransAnyCont b m => MonadAnyCont b (AnyContT m) where+  anyContToM c = AnyCont.anyContT (liftAnyCont c)++instance Monad m => ScopeAnyCont (AnyContT m) where+  scopeAnyCont = lift . flip AnyCont.runAnyContT return+++instance (Monad m, MonadAnyCont b m) => MonadAnyCont b (StateT s m) where+  anyContToM x = lift $ anyContToM x++instance ScopeAnyCont m => ScopeAnyCont (StateT s m) where+  scopeAnyCont = StateT . (scopeAnyCont .) . runStateT+++instance (Monad m, MonadAnyCont b m) => MonadAnyCont b (ExceptT e m) where+  anyContToM x = lift $ anyContToM x+++instance ScopeAnyCont m => ScopeAnyCont (ExceptT e m) where+  scopeAnyCont = mapExceptT scopeAnyCont++class MonadTransAnyCont b m where+  liftAnyCont :: (forall r . (a -> b r) -> b r) -> (forall r . (a -> m r) -> m r)++instance MonadTransAnyCont b b where+  liftAnyCont c = c++instance MonadTransAnyCont b m => MonadTransAnyCont b (StateT s m) where+  liftAnyCont c = (\c q -> StateT $ \s -> c $ ($ s) . runStateT . q) (liftAnyCont c)++instance MonadTransAnyCont b m => MonadTransAnyCont b (ExceptT e m) where+  liftAnyCont c = (\c q -> ExceptT . c $ runExceptT . q) (liftAnyCont c)
+ src/Control/Monad/Trans/AnyCont.hs view
@@ -0,0 +1,40 @@+{-# LANGUAGE+  RankNTypes+  #-}+module Control.Monad.Trans.AnyCont where++import LLVM.Prelude++import Control.Monad.Cont++newtype AnyContT m a = AnyContT { unAnyContT :: forall r . ContT r m a }++instance Functor (AnyContT m) where+  fmap f p = AnyContT $ fmap f . unAnyContT $ p++instance Applicative (AnyContT m) where+  pure a = AnyContT $ pure a+  f <*> v = AnyContT $ unAnyContT f <*> unAnyContT v++instance Monad m => Monad (AnyContT m) where+  AnyContT f >>= k = AnyContT $ f >>= unAnyContT . k+  return a = AnyContT $ return a+  fail s = AnyContT (ContT (\_ -> fail s))+  +instance MonadIO m => MonadIO (AnyContT m) where+  liftIO = lift . liftIO++instance MonadTrans AnyContT where+  lift ma = AnyContT (lift ma)++runAnyContT :: AnyContT m a -> (forall r . (a -> m r) -> m r)+runAnyContT = runContT . unAnyContT+anyContT :: (forall r . (a -> m r) -> m r) -> AnyContT m a+anyContT f = AnyContT (ContT f)++withAnyContT :: (forall r . (b -> m r) -> (a -> m r)) -> AnyContT m a -> AnyContT m b+withAnyContT f m = anyContT $ runAnyContT m . f++mapAnyContT :: (forall r . m r -> m r) -> AnyContT m a -> AnyContT m a+mapAnyContT f m = anyContT $ f . runAnyContT m+
+ src/LLVM.hs view
@@ -0,0 +1,7 @@+-- | An interface to use LLVM in all capacities+module LLVM (+  module LLVM.Module+  ) where++import LLVM.Module+
+ src/LLVM/Analysis.hs view
@@ -0,0 +1,8 @@+-- | functionality for analyzing 'LLVM.Module.Module's.  Much of the analysis+-- possible with LLVM is managed internally, as needed by 'Transforms', and so is not+-- yet exposed here.+module LLVM.Analysis (+  verify+  ) where++import LLVM.Internal.Analysis
+ src/LLVM/CodeGenOpt.hs view
@@ -0,0 +1,12 @@+-- | Code generation options, used in specifying TargetMachine+module LLVM.CodeGenOpt where++import LLVM.Prelude++-- | <http://llvm.org/doxygen/namespacellvm_1_1CodeGenOpt.html>+data Level+    = None+    | Less+    | Default+    | Aggressive+    deriving (Eq, Ord, Read, Show, Typeable, Data)
+ src/LLVM/CodeModel.hs view
@@ -0,0 +1,14 @@+-- | Relocations, used in specifying TargetMachine+module LLVM.CodeModel where++import LLVM.Prelude++-- | <http://llvm.org/doxygen/namespacellvm_1_1CodeModel.html>+data Model+    = Default+    | JITDefault+    | Small+    | Kernel+    | Medium+    | Large+    deriving (Eq, Read, Show, Typeable, Data)
+ src/LLVM/CommandLine.hs view
@@ -0,0 +1,8 @@+-- | Tools for processing command line arguments, for command line tools build+-- with llvm (or for other uses forced into pretending to be such to get at (ack)+-- global state).+module LLVM.CommandLine (+  parseCommandLineOptions+) where++import LLVM.Internal.CommandLine
+ src/LLVM/Context.hs view
@@ -0,0 +1,7 @@+-- | functions for the LLVM Context object which holds thread-scope state+module LLVM.Context (+  Context,+  withContext+  ) where++import LLVM.Internal.Context
+ src/LLVM/Diagnostic.hs view
@@ -0,0 +1,33 @@+-- | Diagnostics describe parse errors+module LLVM.Diagnostic (+  DiagnosticKind(..),+  Diagnostic(..),+  diagnosticDisplay+ ) where++import LLVM.Prelude++-- | What kind of problem does a diagnostic describe?+data DiagnosticKind +  = ErrorKind+  | WarningKind+  | NoteKind+  deriving (Eq, Ord, Read, Show, Typeable, Data)++-- | A 'Diagnostic' described a problem during parsing of LLVM IR+data Diagnostic = Diagnostic {+    lineNumber :: Int,+    columnNumber :: Int,+    diagnosticKind :: DiagnosticKind,+    filename :: String,+    message :: String,+    lineContents :: String+  }+  deriving (Eq, Ord, Read, Show)++-- | Convert a 'Diagnostic' to a printable form.+diagnosticDisplay :: Diagnostic -> String+diagnosticDisplay d = +  (filename d) ++ ":" ++ show (lineNumber d) ++ ":" ++ show (columnNumber d)+  ++ ":\n" ++ show (diagnosticKind d) ++ ": " ++ (message d) ++ "\n"+  ++ (lineContents d) ++ "\n"
+ src/LLVM/ExecutionEngine.hs view
@@ -0,0 +1,8 @@+-- | Tools for JIT execution+module LLVM.ExecutionEngine (+  ExecutionEngine(..),+  ExecutableModule,+  MCJIT, withMCJIT+  ) where++import LLVM.Internal.ExecutionEngine
+ src/LLVM/Internal/Analysis.hs view
@@ -0,0 +1,24 @@+module LLVM.Internal.Analysis where++import LLVM.Prelude++import Control.Monad.AnyCont+import Control.Monad.Error.Class+import Control.Monad.IO.Class+import Control.Monad.Trans.Except++import qualified LLVM.Internal.FFI.Analysis as FFI+import qualified LLVM.Internal.FFI.LLVMCTypes as FFI++import LLVM.Internal.Module+import LLVM.Internal.Coding++-- | Run basic sanity checks on a 'Module'. Note that the same checks will trigger assertions+-- within LLVM if LLVM was built with them turned on, before this function can be is called.+verify :: Module -> ExceptT String IO ()+verify m = flip runAnyContT return $ do+  errorPtr <- alloca+  m' <- readModule m+  result <- decodeM =<< (liftIO $ FFI.verifyModule m' FFI.verifierFailureActionReturnStatus errorPtr)+  when result $ throwError =<< decodeM errorPtr+
+ src/LLVM/Internal/Atomicity.hs view
@@ -0,0 +1,49 @@+{-# LANGUAGE+  TemplateHaskell,+  MultiParamTypeClasses+  #-}+module LLVM.Internal.Atomicity where++import LLVM.Prelude++import Data.Maybe++import qualified LLVM.Internal.FFI.LLVMCTypes as FFI++import LLVM.Internal.Coding+import qualified LLVM.AST as A++genCodingInstance [t| Maybe A.MemoryOrdering |] ''FFI.MemoryOrdering [+  (FFI.memoryOrderingNotAtomic, Nothing),+  (FFI.memoryOrderingUnordered, Just A.Unordered),+  (FFI.memoryOrderingMonotonic, Just A.Monotonic),+  (FFI.memoryOrderingAcquire, Just A.Acquire),+  (FFI.memoryOrderingRelease, Just A.Release),+  (FFI.memoryOrderingAcquireRelease, Just A.AcquireRelease),+  (FFI.memoryOrderingSequentiallyConsistent, Just A.SequentiallyConsistent)+ ]++genCodingInstance [t| A.SynchronizationScope |] ''FFI.SynchronizationScope [+  (FFI.synchronizationScopeSingleThread, A.SingleThread),+  (FFI.synchronizationScopeCrossThread, A.CrossThread)+ ]++instance Monad m => EncodeM m (Maybe A.Atomicity) (FFI.SynchronizationScope, FFI.MemoryOrdering) where+  encodeM a =+    return (,) `ap` encodeM (maybe A.SingleThread fst a) `ap` encodeM (liftM snd a)++instance Monad m => DecodeM m (Maybe A.Atomicity) (FFI.SynchronizationScope, FFI.MemoryOrdering) where+  decodeM (ss, ao) = return (liftM . (,)) `ap` decodeM ss `ap` decodeM ao++instance Monad m => EncodeM m A.Atomicity (FFI.SynchronizationScope, FFI.MemoryOrdering) where+  encodeM = encodeM . Just++instance Monad m => DecodeM m A.Atomicity (FFI.SynchronizationScope, FFI.MemoryOrdering) where+  decodeM = liftM fromJust . decodeM++instance Monad m => EncodeM m A.MemoryOrdering FFI.MemoryOrdering where+  encodeM = encodeM . Just++instance Monad m => DecodeM m A.MemoryOrdering FFI.MemoryOrdering where+  decodeM = liftM fromJust . decodeM+
+ src/LLVM/Internal/Attribute.hs view
@@ -0,0 +1,279 @@+{-# LANGUAGE+  MultiParamTypeClasses,+  ConstraintKinds,+  QuasiQuotes,+  UndecidableInstances,+  RankNTypes+  #-}+module LLVM.Internal.Attribute where++import LLVM.Prelude++import Control.Monad.AnyCont+import Control.Monad.IO.Class+import Control.Monad.State (gets)++import Foreign.C (CUInt)+import Foreign.Ptr+import Data.Either+import Data.Map (Map)+import qualified Data.Map as Map+import Data.Maybe++import qualified LLVM.Internal.FFI.Attribute as FFI+import qualified LLVM.Internal.FFI.LLVMCTypes as FFI+import LLVM.Internal.FFI.LLVMCTypes (parameterAttributeKindP, functionAttributeKindP)  ++import qualified LLVM.AST.ParameterAttribute as A.PA  +import qualified LLVM.AST.FunctionAttribute as A.FA  ++import LLVM.Internal.Coding+import LLVM.Internal.Context  +import LLVM.Internal.EncodeAST+import LLVM.Internal.DecodeAST++inconsistentCases :: Show a => String -> a -> b+inconsistentCases name attr =+  error $ "llvm-hs internal error: cases inconstistent in " ++ name ++ " encoding for " ++ show attr++instance Monad m => EncodeM m A.PA.ParameterAttribute (Ptr FFI.ParameterAttrBuilder -> EncodeAST ()) where+  encodeM a = return $ \b -> liftIO $ case a of+    A.PA.Alignment v -> FFI.attrBuilderAddAlignment b v+    A.PA.Dereferenceable v -> FFI.attrBuilderAddDereferenceable b v+    A.PA.DereferenceableOrNull v -> FFI.attrBuilderAddDereferenceableOrNull b v+    _ -> FFI.attrBuilderAddParameterAttributeKind b $ case a of+      A.PA.ZeroExt -> FFI.parameterAttributeKindZExt+      A.PA.SignExt -> FFI.parameterAttributeKindSExt+      A.PA.InReg -> FFI.parameterAttributeKindInReg+      A.PA.SRet -> FFI.parameterAttributeKindStructRet+      A.PA.NoAlias -> FFI.parameterAttributeKindNoAlias+      A.PA.ByVal -> FFI.parameterAttributeKindByVal+      A.PA.NoCapture -> FFI.parameterAttributeKindNoCapture+      A.PA.Nest -> FFI.parameterAttributeKindNest+      A.PA.ReadOnly -> FFI.parameterAttributeKindReadOnly+      A.PA.ReadNone -> FFI.parameterAttributeKindReadNone+      A.PA.InAlloca -> FFI.parameterAttributeKindInAlloca+      A.PA.NonNull -> FFI.parameterAttributeKindNonNull+      A.PA.Returned -> FFI.parameterAttributeKindReturned+      A.PA.SwiftSelf -> FFI.parameterAttributeKindSwiftSelf+      A.PA.SwiftError -> FFI.parameterAttributeKindSwiftError+      A.PA.WriteOnly -> FFI.parameterAttributeKindWriteOnly+      A.PA.Alignment _ -> inconsistentCases "ParameterAttribute" a+      A.PA.Dereferenceable _ -> inconsistentCases "ParameterAttribute" a+      A.PA.DereferenceableOrNull _ -> inconsistentCases "ParameterAttribute" a++instance Monad m => EncodeM m A.FA.FunctionAttribute (Ptr FFI.FunctionAttrBuilder -> EncodeAST ()) where+  encodeM (A.FA.StringAttribute kind value) = return $ \b -> do+    (kindP, kindLen) <- encodeM kind+    (valueP, valueLen) <- encodeM value+    liftIO $ FFI.attrBuilderAddStringAttribute b kindP kindLen valueP valueLen+  encodeM a = return $ \b -> case a of+    A.FA.StackAlignment v -> liftIO $ FFI.attrBuilderAddStackAlignment b v+    A.FA.AllocSize x y -> do+      x' <- encodeM x+      y' <- encodeM y+      liftIO $ FFI.attrBuilderAddAllocSize b x' y'+    _ -> liftIO $ FFI.attrBuilderAddFunctionAttributeKind b $ case a of+      A.FA.Convergent -> FFI.functionAttributeKindConvergent+      A.FA.InaccessibleMemOnly -> FFI.functionAttributeKindInaccessibleMemOnly+      A.FA.InaccessibleMemOrArgMemOnly -> FFI.functionAttributeKindInaccessibleMemOrArgMemOnly+      A.FA.NoReturn -> FFI.functionAttributeKindNoReturn+      A.FA.NoUnwind -> FFI.functionAttributeKindNoUnwind+      A.FA.ReadNone -> FFI.functionAttributeKindReadNone+      A.FA.ReadOnly -> FFI.functionAttributeKindReadOnly+      A.FA.NoInline -> FFI.functionAttributeKindNoInline+      A.FA.NoRecurse -> FFI.functionAttributeKindNoRecurse+      A.FA.AlwaysInline -> FFI.functionAttributeKindAlwaysInline+      A.FA.MinimizeSize -> FFI.functionAttributeKindMinSize+      A.FA.OptimizeForSize -> FFI.functionAttributeKindOptimizeForSize+      A.FA.OptimizeNone -> FFI.functionAttributeKindOptimizeForSize+      A.FA.WriteOnly -> FFI.functionAttributeKindWriteOnly+      A.FA.ArgMemOnly -> FFI.functionAttributeKindArgMemOnly+      A.FA.StackProtect -> FFI.functionAttributeKindStackProtect+      A.FA.StackProtectReq -> FFI.functionAttributeKindStackProtectReq+      A.FA.StackProtectStrong -> FFI.functionAttributeKindStackProtectStrong+      A.FA.NoRedZone -> FFI.functionAttributeKindNoRedZone+      A.FA.NoImplicitFloat -> FFI.functionAttributeKindNoImplicitFloat+      A.FA.Naked -> FFI.functionAttributeKindNaked+      A.FA.InlineHint -> FFI.functionAttributeKindInlineHint+      A.FA.ReturnsTwice -> FFI.functionAttributeKindReturnsTwice+      A.FA.UWTable -> FFI.functionAttributeKindUWTable+      A.FA.NonLazyBind -> FFI.functionAttributeKindNonLazyBind+      A.FA.Builtin -> FFI.functionAttributeKindBuiltin+      A.FA.NoBuiltin -> FFI.functionAttributeKindNoBuiltin+      A.FA.Cold -> FFI.functionAttributeKindCold+      A.FA.JumpTable -> FFI.functionAttributeKindJumpTable+      A.FA.NoDuplicate -> FFI.functionAttributeKindNoDuplicate+      A.FA.SanitizeAddress -> FFI.functionAttributeKindSanitizeAddress+      A.FA.SanitizeThread -> FFI.functionAttributeKindSanitizeThread+      A.FA.SanitizeMemory -> FFI.functionAttributeKindSanitizeMemory+      A.FA.SafeStack -> FFI.functionAttributeKindSafeStack+      A.FA.StackAlignment _ -> inconsistentCases "FunctionAttribute" a+      A.FA.AllocSize _ _ -> inconsistentCases "FunctionAttribute" a+      A.FA.StringAttribute _ _ -> inconsistentCases "FunctionAttribute" a++instance DecodeM DecodeAST A.PA.ParameterAttribute FFI.ParameterAttribute where+  decodeM a = do+    enum <- liftIO $ FFI.parameterAttributeKindAsEnum a+    case enum of+      [parameterAttributeKindP|ZExt|] -> return A.PA.ZeroExt+      [parameterAttributeKindP|SExt|] -> return A.PA.SignExt+      [parameterAttributeKindP|InReg|] -> return A.PA.InReg+      [parameterAttributeKindP|StructRet|] -> return A.PA.SRet+      [parameterAttributeKindP|Alignment|] -> return A.PA.Alignment `ap` (liftIO $ FFI.attributeValueAsInt a)+      [parameterAttributeKindP|NoAlias|] -> return A.PA.NoAlias+      [parameterAttributeKindP|ByVal|] -> return A.PA.ByVal+      [parameterAttributeKindP|NoCapture|] -> return A.PA.NoCapture+      [parameterAttributeKindP|Nest|] -> return A.PA.Nest+      [parameterAttributeKindP|ReadOnly|] -> return A.PA.ReadOnly+      [parameterAttributeKindP|ReadNone|] -> return A.PA.ReadNone+      [parameterAttributeKindP|WriteOnly|] -> return A.PA.WriteOnly+      [parameterAttributeKindP|InAlloca|] -> return A.PA.InAlloca+      [parameterAttributeKindP|NonNull|] -> return A.PA.NonNull+      [parameterAttributeKindP|Dereferenceable|] -> return A.PA.Dereferenceable `ap` (liftIO $ FFI.attributeValueAsInt a)+      [parameterAttributeKindP|DereferenceableOrNull|] -> return A.PA.DereferenceableOrNull `ap` (liftIO $ FFI.attributeValueAsInt a)+      [parameterAttributeKindP|Returned|] -> return A.PA.Returned+      [parameterAttributeKindP|SwiftSelf|] -> return A.PA.SwiftSelf+      [parameterAttributeKindP|SwiftError|] -> return A.PA.SwiftError+      _ -> error $ "unhandled parameter attribute enum value: " ++ show enum++instance DecodeM DecodeAST A.FA.FunctionAttribute FFI.FunctionAttribute where+  decodeM a = do+    isString <- decodeM =<< (liftIO $ FFI.isStringAttribute a)+    if isString+       then+         return A.FA.StringAttribute+                  `ap` (decodeM $ FFI.attributeKindAsString a)+                  `ap` (decodeM $ FFI.attributeValueAsString a)                   +       else do+         enum <- liftIO $ FFI.functionAttributeKindAsEnum a+         case enum of+           [functionAttributeKindP|AllocSize|] -> do+             x <- alloca+             y <- alloca+             isJust <- liftIO $ FFI.attributeGetAllocSizeArgs a x y+             x' <- decodeM =<< peek x+             y' <- peek y+             yM <- decodeM (y', isJust)+             return (A.FA.AllocSize x' yM)+           [functionAttributeKindP|NoReturn|] -> return A.FA.NoReturn+           [functionAttributeKindP|NoUnwind|] -> return A.FA.NoUnwind+           [functionAttributeKindP|ReadNone|] -> return A.FA.ReadNone+           [functionAttributeKindP|ReadOnly|] -> return A.FA.ReadOnly+           [functionAttributeKindP|NoInline|] -> return A.FA.NoInline+           [functionAttributeKindP|NoRecurse|] -> return A.FA.NoRecurse+           [functionAttributeKindP|AlwaysInline|] -> return A.FA.AlwaysInline+           [functionAttributeKindP|MinSize|] -> return A.FA.MinimizeSize+           [functionAttributeKindP|OptimizeForSize|] -> return A.FA.OptimizeForSize+           [functionAttributeKindP|OptimizeNone|] -> return A.FA.OptimizeForSize+           [functionAttributeKindP|StackProtect|] -> return A.FA.StackProtect+           [functionAttributeKindP|StackProtectReq|] -> return A.FA.StackProtectReq+           [functionAttributeKindP|StackProtectStrong|] -> return A.FA.StackProtectStrong+           [functionAttributeKindP|NoRedZone|] -> return A.FA.NoRedZone+           [functionAttributeKindP|NoImplicitFloat|] -> return A.FA.NoImplicitFloat+           [functionAttributeKindP|Naked|] -> return A.FA.Naked+           [functionAttributeKindP|InlineHint|] -> return A.FA.InlineHint+           [functionAttributeKindP|StackAlignment|] -> return A.FA.StackAlignment `ap` (liftIO $ FFI.attributeValueAsInt a)+           [functionAttributeKindP|ReturnsTwice|] -> return A.FA.ReturnsTwice+           [functionAttributeKindP|UWTable|] -> return A.FA.UWTable+           [functionAttributeKindP|NonLazyBind|] -> return A.FA.NonLazyBind+           [functionAttributeKindP|Builtin|] -> return A.FA.Builtin+           [functionAttributeKindP|NoBuiltin|] -> return A.FA.NoBuiltin+           [functionAttributeKindP|Cold|] -> return A.FA.Cold+           [functionAttributeKindP|JumpTable|] -> return A.FA.JumpTable+           [functionAttributeKindP|NoDuplicate|] -> return A.FA.NoDuplicate+           [functionAttributeKindP|SanitizeAddress|] -> return A.FA.SanitizeAddress+           [functionAttributeKindP|SanitizeThread|] -> return A.FA.SanitizeThread+           [functionAttributeKindP|SanitizeMemory|] -> return A.FA.SanitizeMemory+           [functionAttributeKindP|ArgMemOnly|] -> return A.FA.ArgMemOnly+           [functionAttributeKindP|Convergent|] -> return A.FA.Convergent+           [functionAttributeKindP|InaccessibleMemOnly|] -> return A.FA.InaccessibleMemOnly+           [functionAttributeKindP|InaccessibleMemOrArgMemOnly|] -> return A.FA.InaccessibleMemOrArgMemOnly+           [functionAttributeKindP|SafeStack|] -> return A.FA.SafeStack+           [functionAttributeKindP|WriteOnly|] -> return A.FA.WriteOnly+           _ -> error $ "unhandled function attribute enum value: " ++ show enum++allocaAttrBuilder :: (Monad m, MonadAnyCont IO m) => m (Ptr (FFI.AttrBuilder a))+allocaAttrBuilder = do+  p <- allocaArray FFI.getAttrBuilderSize+  anyContToM $ \f -> do+    ab <- FFI.constructAttrBuilder p+    r <- f ab+    FFI.destroyAttrBuilder ab+    return r++instance EncodeM EncodeAST a (Ptr (FFI.AttrBuilder b) -> EncodeAST ()) => EncodeM EncodeAST (FFI.Index, [a]) (FFI.AttributeSet b) where+  encodeM (index, as) = scopeAnyCont $ do+    ab <- allocaAttrBuilder+    builds <- mapM encodeM as+    forM builds ($ ab) :: EncodeAST [()]+    Context context <- gets encodeStateContext+    liftIO $ FFI.getAttributeSet context index ab++instance EncodeM EncodeAST [A.FA.FunctionAttribute] FFI.FunctionAttributeSet where+  encodeM fas = encodeM (FFI.functionIndex, fas)++instance DecodeM DecodeAST a (FFI.Attribute b) => DecodeM DecodeAST [a] (FFI.AttributeSet b) where+  decodeM as = do+    np <- alloca+    as <- liftIO $ FFI.attributeSetGetAttributes as 0 np+    n <- peek np+    decodeM (n, as)+            +data MixedAttributeSet = MixedAttributeSet {+    functionAttributes :: [Either A.FA.GroupID A.FA.FunctionAttribute],+    returnAttributes :: [A.PA.ParameterAttribute],+    parameterAttributes :: Map CUInt [A.PA.ParameterAttribute]+  }+  deriving (Eq, Show)++data PreSlot+  = IndirectFunctionAttributes A.FA.GroupID+  | DirectFunctionAttributes [A.FA.FunctionAttribute]+  | ReturnAttributes [A.PA.ParameterAttribute]+  | ParameterAttributes CUInt [A.PA.ParameterAttribute]    ++instance EncodeM EncodeAST PreSlot FFI.MixedAttributeSet where+  encodeM preSlot = do+    let forget = liftM FFI.forgetAttributeType+    case preSlot of+      IndirectFunctionAttributes gid -> forget (referAttributeGroup gid)+      DirectFunctionAttributes fas -> forget (encodeM fas :: EncodeAST FFI.FunctionAttributeSet)+      ReturnAttributes as -> forget (encodeM (FFI.returnIndex, as) :: EncodeAST FFI.ParameterAttributeSet)+      ParameterAttributes i as -> forget (encodeM (fromIntegral (i + 1) :: FFI.Index, as) :: EncodeAST FFI.ParameterAttributeSet)++instance EncodeM EncodeAST MixedAttributeSet FFI.MixedAttributeSet where+  encodeM (MixedAttributeSet fAttrs rAttrs pAttrs) = do+    let directP = DirectFunctionAttributes (rights fAttrs)+        indirectPs = map IndirectFunctionAttributes (lefts fAttrs)+        returnP = ReturnAttributes rAttrs+        paramPs = [ ParameterAttributes x as | (x, as) <- Map.toList pAttrs ]+    (nAttrs, attrs) <- encodeM ([directP, returnP] ++ indirectPs ++ paramPs)+    Context context <- gets encodeStateContext+    liftIO $ FFI.mixAttributeSets context attrs nAttrs++instance DecodeM DecodeAST MixedAttributeSet FFI.MixedAttributeSet where+  decodeM mas = do+    numSlots <- if mas == nullPtr then return 0 else liftIO $ FFI.attributeSetNumSlots mas+    slotIndexes <- forM (take (fromIntegral numSlots) [0..]) $ \s -> do+      i <- liftIO $ FFI.attributeSetSlotIndex mas s+      return (i, s)+    let separate :: Ord k => k -> Map k a -> (Maybe a, Map k a)+        separate = Map.updateLookupWithKey (\_ _ -> Nothing)+        indexedSlots = Map.fromList slotIndexes+    unless (Map.size indexedSlots == length slotIndexes) $+           fail "unexpected slot index collision decoding mixed AttributeSet"+    let (functionSlot, otherSlots) = separate FFI.functionIndex (Map.fromList slotIndexes)+    functionAnnotation <- for (maybeToList functionSlot) $ \slot -> do+      a <- liftIO $ FFI.attributeSetSlotAttributes mas slot+      getAttributeGroupID a+    otherAttributeSets <- for otherSlots $ \slot -> do+      a <- liftIO $ FFI.attributeSetSlotAttributes mas slot+      decodeM (a :: FFI.ParameterAttributeSet)+    let (returnAttributeSet, shiftedParameterAttributeSets) = separate FFI.returnIndex otherAttributeSets+    return $ MixedAttributeSet {+                  functionAttributes = fmap Left functionAnnotation,+                  returnAttributes = join . maybeToList $ returnAttributeSet,+                  parameterAttributes = Map.mapKeysMonotonic (\x -> fromIntegral x - 1) shiftedParameterAttributeSets+                }+
+ src/LLVM/Internal/BasicBlock.hs view
@@ -0,0 +1,27 @@+module LLVM.Internal.BasicBlock where++import LLVM.Prelude++import Control.Monad.Trans+import Foreign.Ptr++import qualified LLVM.Internal.FFI.PtrHierarchy as FFI+import qualified LLVM.Internal.FFI.BasicBlock as FFI+import qualified LLVM.Internal.FFI.Iterate as FFI++import LLVM.Internal.DecodeAST+import LLVM.Internal.Coding+import LLVM.Internal.Instruction ()++import qualified LLVM.AST.Instruction as A++getBasicBlockTerminator :: Ptr FFI.BasicBlock -> DecodeAST (DecodeAST (A.Named A.Terminator))+getBasicBlockTerminator = decodeM <=< (liftIO . FFI.getBasicBlockTerminator)++getNamedInstructions :: Ptr FFI.BasicBlock -> DecodeAST (DecodeAST [A.Named A.Instruction])+getNamedInstructions b = do+  ffiInstructions <- liftIO $ FFI.getXs (FFI.getFirstInstruction b) FFI.getNextInstruction+  let n = length ffiInstructions+  liftM sequence . forM (take (n-1) ffiInstructions) $ decodeM++  
+ src/LLVM/Internal/CallingConvention.hs view
@@ -0,0 +1,71 @@+{-# LANGUAGE+  MultiParamTypeClasses,+  TemplateHaskell,+  QuasiQuotes+  #-}+module LLVM.Internal.CallingConvention where++import LLVM.Prelude++import LLVM.Internal.Coding+import Foreign.C.Types (CUInt(..))++import qualified LLVM.Internal.FFI.LLVMCTypes as FFI+import LLVM.Internal.FFI.LLVMCTypes (callingConventionP)++import qualified LLVM.AST.CallingConvention as A.CC++instance Monad m => EncodeM m A.CC.CallingConvention FFI.CallingConvention where+  encodeM cc = return $ +        case cc of+          A.CC.C -> FFI.callingConventionC+          A.CC.Fast -> FFI.callingConventionFast+          A.CC.Cold -> FFI.callingConventionCold+          A.CC.GHC ->  FFI.callingConventionGHC+          A.CC.HiPE -> FFI.callingConventionHiPE+          A.CC.WebKit_JS -> FFI.callingConventionWebKit_JS+          A.CC.AnyReg -> FFI.callingConventionAnyReg+          A.CC.PreserveMost -> FFI.callingConventionPreserveMost+          A.CC.PreserveAll -> FFI.callingConventionPreserveAll+          A.CC.X86_StdCall -> FFI.callingConventionX86_StdCall+          A.CC.X86_FastCall -> FFI.callingConventionX86_FastCall+          A.CC.ARM_APCS -> FFI.callingConventionARM_APCS+          A.CC.ARM_AAPCS -> FFI.callingConventionARM_AAPCS+          A.CC.ARM_AAPCS_VFP -> FFI.callingConventionARM_AAPCS_VFP+          A.CC.MSP430_INTR -> FFI.callingConventionMSP430_INTR+          A.CC.X86_ThisCall -> FFI.callingConventionX86_ThisCall+          A.CC.PTX_Kernel -> FFI.callingConventionPTX_Kernel+          A.CC.PTX_Device -> FFI.callingConventionPTX_Device+          A.CC.SPIR_FUNC -> FFI.callingConventionSPIR_FUNC+          A.CC.SPIR_KERNEL -> FFI.callingConventionSPIR_KERNEL+          A.CC.Intel_OCL_BI -> FFI.callingConventionIntel_OCL_BI+          A.CC.X86_64_SysV -> FFI.callingConventionX86_64_SysV+          A.CC.X86_64_Win64 -> FFI.callingConventionX86_64_Win64+          A.CC.Numbered cc' -> FFI.CallingConvention (fromIntegral cc')++instance Monad m => DecodeM m A.CC.CallingConvention FFI.CallingConvention where+  decodeM cc = return $ case cc of+    [callingConventionP|C|] -> A.CC.C+    [callingConventionP|Fast|] -> A.CC.Fast+    [callingConventionP|Cold|] -> A.CC.Cold+    [callingConventionP|GHC|] -> A.CC.GHC+    [callingConventionP|HiPE|] -> A.CC.HiPE+    [callingConventionP|WebKit_JS|] -> A.CC.WebKit_JS+    [callingConventionP|AnyReg|] -> A.CC.AnyReg+    [callingConventionP|PreserveMost|] -> A.CC.PreserveMost+    [callingConventionP|PreserveAll|] -> A.CC.PreserveAll+    [callingConventionP|X86_StdCall|] -> A.CC.X86_StdCall+    [callingConventionP|X86_FastCall|] -> A.CC.X86_FastCall+    [callingConventionP|ARM_APCS|] -> A.CC.ARM_APCS+    [callingConventionP|ARM_AAPCS|] -> A.CC.ARM_AAPCS+    [callingConventionP|ARM_AAPCS_VFP|] -> A.CC.ARM_AAPCS_VFP+    [callingConventionP|MSP430_INTR|] -> A.CC.MSP430_INTR+    [callingConventionP|X86_ThisCall|] -> A.CC.X86_ThisCall+    [callingConventionP|PTX_Kernel|] -> A.CC.PTX_Kernel+    [callingConventionP|PTX_Device|] -> A.CC.PTX_Device+    [callingConventionP|SPIR_FUNC|] -> A.CC.SPIR_FUNC+    [callingConventionP|SPIR_KERNEL|] -> A.CC.SPIR_KERNEL+    [callingConventionP|Intel_OCL_BI|] -> A.CC.Intel_OCL_BI+    [callingConventionP|X86_64_SysV|] -> A.CC.X86_64_SysV+    [callingConventionP|X86_64_Win64|] -> A.CC.X86_64_Win64+    FFI.CallingConvention (CUInt ci) | ci >= 64 -> A.CC.Numbered (fromIntegral ci)
+ src/LLVM/Internal/Coding.hs view
@@ -0,0 +1,140 @@+{-# LANGUAGE+  TemplateHaskell,+  MultiParamTypeClasses,+  FunctionalDependencies,+  UndecidableInstances+  #-}+module LLVM.Internal.Coding where++import LLVM.Prelude++import Language.Haskell.TH+import Language.Haskell.TH.Quote++import Control.Monad.AnyCont+import Control.Monad.IO.Class++import Foreign.C+import Foreign.Ptr+import Foreign.Storable+import Foreign.Marshal.Alloc+import Foreign.Marshal.Array++import qualified LLVM.Internal.FFI.LLVMCTypes as FFI++class EncodeM e h c where+  encodeM :: h -> e c++class DecodeM d h c where+  decodeM :: c -> d h++genCodingInstance :: (Data c, Data h) => TypeQ -> Name -> [(c, h)] -> Q [Dec]+genCodingInstance ht ctn chs = do+  let n = const Nothing+  [d| +    instance Monad m => EncodeM m $(ht) $(conT ctn) where+      encodeM h = return $ $(+        caseE [| h |] [ match (dataToPatQ n h) (normalB (dataToExpQ n c)) [] | (c,h) <- chs ] +       )++    instance Monad m => DecodeM m $(ht) $(conT ctn) where+      decodeM c = return $ $(+        caseE [| c |] [ match (dataToPatQ n c) (normalB (dataToExpQ n h)) [] | (c,h) <- chs ]+       )+   |]++allocaArray :: (Integral i, Storable a, MonadAnyCont IO m) => i -> m (Ptr a)+allocaArray p = anyContToM $ Foreign.Marshal.Array.allocaArray (fromIntegral p)++alloca :: (Storable a, MonadAnyCont IO m) => m (Ptr a)+alloca = anyContToM Foreign.Marshal.Alloc.alloca++peek :: (Storable a, MonadIO m) => Ptr a -> m a+peek p = liftIO $ Foreign.Storable.peek p++peekByteOff :: (Storable a, MonadIO m) => Ptr a -> Int -> m a+peekByteOff p i = liftIO $ Foreign.Storable.peekByteOff p i++poke :: (Storable a, MonadIO m) => Ptr a -> a -> m ()+poke p a = liftIO $ Foreign.Storable.poke p a++pokeByteOff :: (Storable a, MonadIO m) => Ptr a -> Int -> a -> m ()+pokeByteOff p i a = liftIO $ Foreign.Storable.pokeByteOff p i a++peekArray :: (Integral i, Storable a, MonadIO m) => i -> Ptr a -> m [a]+peekArray n p = liftIO $ Foreign.Marshal.Array.peekArray (fromIntegral n) p++instance (Monad m, EncodeM m h c, Storable c, MonadAnyCont IO m) => EncodeM m [h] (CUInt, Ptr c) where+  encodeM hs = do+    hs <- mapM encodeM hs+    (anyContToM $ \x -> Foreign.Marshal.Array.withArrayLen hs $ \n hs -> x (fromIntegral n, hs))++instance (Monad m, DecodeM m h c, Storable c, MonadIO m) => DecodeM m [h] (CUInt, Ptr c) where+  decodeM (n, ca) = do+    cs <- liftIO $ Foreign.Marshal.Array.peekArray (fromIntegral n) ca+    mapM decodeM cs++instance Monad m => EncodeM m Bool FFI.LLVMBool where+  encodeM False = return $ FFI.LLVMBool 0+  encodeM True = return $ FFI.LLVMBool 1++instance Monad m => DecodeM m Bool FFI.LLVMBool where+  decodeM (FFI.LLVMBool 0) = return $ False+  decodeM (FFI.LLVMBool _) = return $ True++instance (Monad m, EncodeM m h (Ptr c)) => EncodeM m (Maybe h) (Ptr c) where+  encodeM = maybe (return nullPtr) encodeM++instance (Monad m, DecodeM m h (Ptr c)) => DecodeM m (Maybe h) (Ptr c) where+  decodeM p | p == nullPtr = return Nothing+            | otherwise = liftM Just $ decodeM p++instance Monad m => EncodeM m (Maybe Bool) (FFI.NothingAsMinusOne Bool) where+  encodeM = return . FFI.NothingAsMinusOne . maybe (-1) (fromIntegral . fromEnum)++instance Monad m => EncodeM m (Maybe Word) (FFI.NothingAsMinusOne Word) where+  encodeM = return . FFI.NothingAsMinusOne . maybe (-1) fromIntegral++instance Monad m => EncodeM m (Maybe Word) (CUInt, FFI.LLVMBool) where+  encodeM (Just a) = liftM2 (,) (encodeM a) (encodeM True)+  encodeM Nothing = return (0,) `ap` (encodeM False)++instance Monad m => DecodeM m (Maybe Word) (CUInt, FFI.LLVMBool) where+  decodeM (a, isJust) = do+    isJust' <- decodeM isJust+    if isJust'+       then liftM Just (decodeM a)+       else return Nothing++instance Monad m => EncodeM m Word CUInt where+  encodeM = return . fromIntegral++instance Monad m => EncodeM m Word32 CUInt where+  encodeM = return . fromIntegral++instance Monad m => EncodeM m Word64 CULong where+  encodeM = return . fromIntegral++instance Monad m => DecodeM m Word CUInt where+  decodeM = return . fromIntegral++instance Monad m => DecodeM m Word32 CUInt where+  decodeM = return . fromIntegral++instance Monad m => DecodeM m Word64 CULong where+  decodeM = return . fromIntegral++instance Monad m => EncodeM m Int32 CInt where+  encodeM = return . fromIntegral++instance Monad m => DecodeM m Int32 CInt where+  decodeM = return . fromIntegral++instance Monad m => DecodeM m Int CInt where+  decodeM = return . fromIntegral++instance Monad m => EncodeM m Word64 Word64 where+  encodeM = return++instance Monad m => DecodeM m Word64 Word64 where+  decodeM = return
+ src/LLVM/Internal/CommandLine.hs view
@@ -0,0 +1,23 @@+module LLVM.Internal.CommandLine where++import LLVM.Prelude++import Control.Monad.AnyCont+import Control.Monad.IO.Class++import Foreign.Ptr++import qualified LLVM.Internal.FFI.CommandLine as FFI++import LLVM.Internal.Coding+import LLVM.Internal.String ()++-- | <http://llvm.org/doxygen/namespacellvm_1_1cl.html#a992a39dae9eb8d4e54ffee5467902803>+-- Sadly, there is occasionally some configuration one would like to control+-- in LLVM which are accessible only as command line flags setting global state,+-- as if the command line tools were the only use of LLVM. Very sad.+parseCommandLineOptions :: [String] -> Maybe String -> IO ()+parseCommandLineOptions args overview = flip runAnyContT return $ do+  args <- encodeM args+  overview <- maybe (return nullPtr) encodeM overview+  liftIO $ FFI.parseCommandLineOptions args overview
+ src/LLVM/Internal/Constant.hs view
@@ -0,0 +1,248 @@+{-# LANGUAGE+  TemplateHaskell,+  QuasiQuotes,+  MultiParamTypeClasses,+  ScopedTypeVariables+  #-}+module LLVM.Internal.Constant where++import LLVM.Prelude++import qualified Language.Haskell.TH as TH+import qualified Language.Haskell.TH.Quote as TH+import qualified LLVM.Internal.InstructionDefs as ID++import Data.Bits+import Control.Monad.State (get, gets, modify, evalState)+import Control.Monad.AnyCont+import Control.Monad.IO.Class++import qualified Data.Map as Map+import Foreign.Ptr+import Foreign.Storable (Storable, sizeOf)++import qualified LLVM.Internal.FFI.Constant as FFI+import qualified LLVM.Internal.FFI.GlobalValue as FFI+import qualified LLVM.Internal.FFI.Instruction as FFI+import qualified LLVM.Internal.FFI.LLVMCTypes as FFI+import LLVM.Internal.FFI.LLVMCTypes (valueSubclassIdP)+import qualified LLVM.Internal.FFI.PtrHierarchy as FFI+import qualified LLVM.Internal.FFI.Type as FFI+import qualified LLVM.Internal.FFI.User as FFI+import qualified LLVM.Internal.FFI.Value as FFI+import qualified LLVM.Internal.FFI.BinaryOperator as FFI++import qualified LLVM.AST.Constant as A (Constant)+import qualified LLVM.AST.Constant as A.C hiding (Constant)+import qualified LLVM.AST.Type as A+import qualified LLVM.AST.IntegerPredicate as A (IntegerPredicate)+import qualified LLVM.AST.FloatingPointPredicate as A (FloatingPointPredicate)+import qualified LLVM.AST.Float as A.F++import LLVM.Internal.Coding+import LLVM.Internal.DecodeAST+import LLVM.Internal.EncodeAST+import LLVM.Internal.Context+import LLVM.Internal.Type ()+import LLVM.Internal.IntegerPredicate ()+import LLVM.Internal.FloatingPointPredicate ()++allocaWords :: forall a m . (Storable a, MonadAnyCont IO m, Monad m, MonadIO m) => Word32 -> m (Ptr a)+allocaWords nBits = do+  allocaArray (((nBits-1) `div` (8*(fromIntegral (sizeOf (undefined :: a))))) + 1)++instance EncodeM EncodeAST A.Constant (Ptr FFI.Constant) where+  encodeM c = scopeAnyCont $ case c of+    A.C.Int { A.C.integerBits = bits, A.C.integerValue = v } -> do+      t <- encodeM (A.IntegerType bits)+      words <- encodeM [+        fromIntegral ((v `shiftR` (w*64)) .&. 0xffffffffffffffff) :: Word64+        | w <- [0 .. ((fromIntegral bits-1) `div` 64)] +       ]+      liftIO $ FFI.constantIntOfArbitraryPrecision t words+    A.C.Float { A.C.floatValue = v } -> do+      Context context <- gets encodeStateContext+      let poke1 f = do+            let nBits = fromIntegral $ 8*(sizeOf f)+            words <- allocaWords nBits+            poke (castPtr words) f+            return (nBits, words)+          poke2 fh fl = do+             let nBits = fromIntegral $ 8*(sizeOf fh) + 8*(sizeOf fl)+             words <- allocaWords nBits+             pokeByteOff (castPtr words) 0 fl+             pokeByteOff (castPtr words) (sizeOf fl) fh+             return (nBits, words)+      (nBits, words) <- case v of+        A.F.Half f -> poke1 f+        A.F.Single f -> poke1 f+        A.F.Double f -> poke1 f+        A.F.X86_FP80 high low -> poke2 high low+        A.F.Quadruple high low -> poke2 high low+        A.F.PPC_FP128 high low -> poke2 high low+      let fpSem = case v of+                    A.F.Half _ -> FFI.floatSemanticsIEEEhalf+                    A.F.Single _ -> FFI.floatSemanticsIEEEsingle+                    A.F.Double _ -> FFI.floatSemanticsIEEEdouble+                    A.F.Quadruple _ _ -> FFI.floatSemanticsIEEEquad+                    A.F.X86_FP80 _ _ -> FFI.floatSemanticsx87DoubleExtended+                    A.F.PPC_FP128 _ _ -> FFI.floatSemanticsPPCDoubleDouble+      nBits <- encodeM nBits+      liftIO $ FFI.constantFloatOfArbitraryPrecision context nBits words fpSem+    A.C.GlobalReference _ n -> FFI.upCast <$> referGlobal n+    A.C.BlockAddress f b -> do+      f' <- referGlobal f+      b' <- getBlockForAddress f b+      liftIO $ FFI.blockAddress (FFI.upCast f') b'+    A.C.Struct nm p ms -> do+      p <- encodeM p+      ms <- encodeM ms+      case nm of+        Nothing -> do+          Context context <- gets encodeStateContext+          liftIO $ FFI.constStructInContext context ms p+        Just nm -> do+          t <- lookupNamedType nm+          liftIO $ FFI.constNamedStruct t ms+    A.C.TokenNone -> do+      Context context <- gets encodeStateContext+      liftIO $ FFI.getConstTokenNone context+    o -> $(do+      let constExprInfo =  ID.outerJoin ID.astConstantRecs (ID.innerJoin ID.astInstructionRecs ID.instructionDefs)+      TH.caseE [| o |] $ do+        (name, (Just (TH.RecC n fs), instrInfo)) <- Map.toList constExprInfo+        let fns = [ TH.mkName . TH.nameBase $ fn | (fn, _, _) <- fs ]+            coreCall n = TH.dyn $ "FFI.constant" ++ n+            buildBody c = [ TH.bindS (TH.varP fn) [| encodeM $(TH.varE fn) |] | fn <- fns ]+                          ++ [ TH.noBindS [| liftIO $(foldl TH.appE c (map TH.varE fns)) |] ]+            hasFlags = any (== ''Bool) [ h | (_, _, TH.ConT h) <- fs ]+        core <- case instrInfo of+          Just (_, iDef) -> do+            let opcode = TH.dataToExpQ (const Nothing) (ID.cppOpcode iDef)+            case ID.instructionKind iDef of+              ID.Binary | hasFlags -> return $ coreCall name+                        | True -> return [| $(coreCall "BinaryOperator") $(opcode) |]+              ID.Cast -> return [| $(coreCall "Cast") $(opcode) |]+              _ -> return $ coreCall name+          Nothing -> if (name `elem` ["Vector", "Null", "Array", "Undef"])+                      then return $ coreCall name+                      else []+        return $ TH.match+          (TH.recP n [(fn,) <$> (TH.varP . TH.mkName . TH.nameBase $ fn) | (fn, _, _) <- fs])+          (TH.normalB (TH.doE (buildBody core)))+          []+      )++instance DecodeM DecodeAST A.Constant (Ptr FFI.Constant) where+  decodeM c = scopeAnyCont $ do+    let v = FFI.upCast c :: Ptr FFI.Value+        u = FFI.upCast c :: Ptr FFI.User+    ft <- liftIO (FFI.typeOf v)+    t <- decodeM ft+    valueSubclassId <- liftIO $ FFI.getValueSubclassId v+    nOps <- liftIO $ FFI.getNumOperands u+    let globalRef = return A.C.GlobalReference +                    `ap` (return t)+                    `ap` (getGlobalName =<< liftIO (FFI.isAGlobalValue v))+        op = decodeM <=< liftIO . FFI.getConstantOperand c+        getConstantOperands = mapM op [0..nOps-1] +        getConstantData = do+          let nElements = case t of+                            A.VectorType n _ -> n+                            A.ArrayType n _ | n <= (fromIntegral (maxBound :: Word32)) -> fromIntegral n+          forM [0..nElements-1] $ do+             decodeM <=< liftIO . FFI.getConstantDataSequentialElementAsConstant c . fromIntegral++    case valueSubclassId of+      [valueSubclassIdP|Function|] -> globalRef+      [valueSubclassIdP|GlobalAlias|] -> globalRef+      [valueSubclassIdP|GlobalVariable|] -> globalRef+      [valueSubclassIdP|ConstantInt|] -> do+        np <- alloca+        wsp <- liftIO $ FFI.getConstantIntWords c np+        n <- peek np+        words <- decodeM (n, wsp)+        return $ A.C.Int (A.typeBits t) (foldr (\b a -> (a `shiftL` 64) .|. fromIntegral b) 0 (words :: [Word64]))+      [valueSubclassIdP|ConstantFP|] -> do+        let A.FloatingPointType nBits fmt = t+        ws <- allocaWords nBits+        liftIO $ FFI.getConstantFloatWords c ws+        A.C.Float <$> (+          case (nBits, fmt) of+            (16, A.IEEE) -> A.F.Half <$> peek (castPtr ws)+            (32, A.IEEE) -> A.F.Single <$> peek (castPtr ws)+            (64, A.IEEE) -> A.F.Double <$> peek (castPtr ws)+            (128, A.IEEE) -> A.F.Quadruple <$> peekByteOff (castPtr ws) 8 <*> peekByteOff (castPtr ws) 0+            (80, A.DoubleExtended) -> A.F.X86_FP80 <$> peekByteOff (castPtr ws) 8 <*> peekByteOff (castPtr ws) 0+            (128, A.PairOfFloats) -> A.F.PPC_FP128 <$> peekByteOff (castPtr ws) 8 <*> peekByteOff (castPtr ws) 0+            _ -> error $ "don't know how to decode floating point constant of type: " ++ show t+          )+      [valueSubclassIdP|ConstantPointerNull|] -> return $ A.C.Null t+      [valueSubclassIdP|ConstantAggregateZero|] -> return $ A.C.Null t+      [valueSubclassIdP|UndefValue|] -> return $ A.C.Undef t+      [valueSubclassIdP|BlockAddress|] -> +            return A.C.BlockAddress +               `ap` (getGlobalName =<< do liftIO $ FFI.isAGlobalValue =<< FFI.getBlockAddressFunction c)+               `ap` (getLocalName =<< do liftIO $ FFI.getBlockAddressBlock c)+      [valueSubclassIdP|ConstantStruct|] -> do+            return A.C.Struct+               `ap` (return $ case t of A.NamedTypeReference n -> Just n; _ -> Nothing)+               `ap` (decodeM =<< liftIO (FFI.isPackedStruct ft))+               `ap` getConstantOperands+      [valueSubclassIdP|ConstantDataArray|] -> +            return A.C.Array `ap` (return $ A.elementType t) `ap` getConstantData+      [valueSubclassIdP|ConstantArray|] -> +            return A.C.Array `ap` (return $ A.elementType t) `ap` getConstantOperands+      [valueSubclassIdP|ConstantDataVector|] -> +            return A.C.Vector `ap` getConstantData+      [valueSubclassIdP|ConstantExpr|] -> do+            cppOpcode <- liftIO $ FFI.getConstantCPPOpcode c+            $(+              TH.caseE [| cppOpcode |] $ do+                (name, ((TH.RecC n fs, _), iDef)) <- Map.toList $+                      ID.innerJoin (ID.innerJoin ID.astConstantRecs ID.astInstructionRecs) ID.instructionDefs+                let apWrapper o (fn, _, ct) = do+                      a <- case ct of+                             TH.ConT h+                               | h == ''A.Constant -> do+                                               operandNumber <- get+                                               modify (+1)+                                               return [| op $(TH.litE . TH.integerL $ operandNumber) |]+                               | h == ''A.Type -> return [| pure t |]+                               | h == ''A.IntegerPredicate -> +                                 return [| liftIO $ decodeM =<< FFI.getConstantICmpPredicate c |]+                               | h == ''A.FloatingPointPredicate -> +                                 return [| liftIO $ decodeM =<< FFI.getConstantFCmpPredicate c |]+                               | h == ''Bool -> case TH.nameBase fn of+                                                  "inBounds" -> return [| liftIO $ decodeM =<< FFI.getInBounds v |]+                                                  "exact" -> return [| liftIO $ decodeM =<< FFI.isExact v |]+                                                  "nsw" -> return [| liftIO $ decodeM =<< FFI.hasNoSignedWrap v |]+                                                  "nuw" -> return [| liftIO $ decodeM =<< FFI.hasNoUnsignedWrap v |]+                                                  x -> error $ "constant bool field " ++ show x ++ " not handled yet"+                             TH.AppT TH.ListT (TH.ConT h) +                               | h == ''Word32 -> +                                  return [|+                                        do+                                          np <- alloca+                                          isp <- liftIO $ FFI.getConstantIndices c np+                                          n <- peek np+                                          decodeM (n, isp)+                                        |]+                               | h == ''A.Constant -> +                                  case TH.nameBase fn of+                                    "indices" -> do+                                      operandNumber <- get+                                      return [| mapM op [$(TH.litE . TH.integerL $ operandNumber)..nOps-1] |]+                             _ -> error $ "unhandled constant expr field type: " ++ show fn ++ " - " ++ show ct+                      return [| $(o) `ap` $(a) |]+                return $ TH.match +                          (TH.dataToPatQ (const Nothing) (ID.cppOpcode iDef))+                          (TH.normalB (evalState (foldM apWrapper [| return $(TH.conE n) |] fs) 0))+                          []+             )+      [valueSubclassIdP|ConstantTokenNone|] -> return A.C.TokenNone+      _ -> error $ "unhandled constant valueSubclassId: " ++ show valueSubclassId+++  +  
+ src/LLVM/Internal/Context.hs view
@@ -0,0 +1,20 @@+module LLVM.Internal.Context where++import LLVM.Prelude++import Control.Exception+import Control.Concurrent++import Foreign.Ptr++import qualified LLVM.Internal.FFI.Context as FFI++-- | a Context object holds the state the of LLVM system needs for one thread of+-- | LLVM compilation. Once upon a time, in early versions of LLVM, this state was global.+-- | Then it got packed up in this object to allow multiple threads to compile at once.+data Context = Context (Ptr FFI.Context)++-- | Create a Context, run an action (to which it is provided), then destroy the Context.+withContext :: (Context -> IO a) -> IO a+withContext = runBound . bracket FFI.contextCreate FFI.contextDispose . (. Context)+  where runBound = if rtsSupportsBoundThreads then runInBoundThread else id
+ src/LLVM/Internal/DataLayout.hs view
@@ -0,0 +1,23 @@+module LLVM.Internal.DataLayout where++import LLVM.Prelude++import Control.Exception+import Control.Monad.AnyCont+import Control.Monad.IO.Class++import Foreign.Ptr++import qualified LLVM.Internal.FFI.DataLayout as FFI++import LLVM.AST.DataLayout+import LLVM.DataLayout++import LLVM.Internal.Coding+import LLVM.Internal.String ()++withFFIDataLayout :: DataLayout -> (Ptr FFI.DataLayout -> IO a) -> IO a+withFFIDataLayout dl f = flip runAnyContT return $ do+  dls <- encodeM (dataLayoutToString dl)+  liftIO $ bracket (FFI.createDataLayout dls) FFI.disposeDataLayout f+
+ src/LLVM/Internal/DecodeAST.hs view
@@ -0,0 +1,172 @@+{-# LANGUAGE+  GeneralizedNewtypeDeriving,+  MultiParamTypeClasses,+  UndecidableInstances+  #-}+module LLVM.Internal.DecodeAST where++import LLVM.Prelude++import Control.Monad.State+import Control.Monad.AnyCont++import Foreign.Ptr+import Foreign.C++import Data.Sequence (Seq)+import qualified Data.Sequence as Seq+import Data.Map (Map)+import qualified Data.Map as Map+import Data.Array (Array)+import qualified Data.Array as Array++import qualified LLVM.Internal.FFI.Attribute as FFI+import qualified LLVM.Internal.FFI.GlobalValue as FFI+import qualified LLVM.Internal.FFI.PtrHierarchy as FFI+import qualified LLVM.Internal.FFI.Value as FFI+import qualified LLVM.Internal.FFI.Type as FFI++import qualified LLVM.AST.Name as A+import qualified LLVM.AST.Operand as A (MetadataNodeID(..))+import qualified LLVM.AST.Attribute as A.A+import qualified LLVM.AST.COMDAT as A.COMDAT++import LLVM.Internal.Coding+import LLVM.Internal.String ()++type NameMap a = Map (Ptr a) Word++data DecodeState = DecodeState {+    globalVarNum :: NameMap FFI.GlobalValue,+    localVarNum :: NameMap FFI.Value,+    localNameCounter :: Maybe Word,+    namedTypeNum :: NameMap FFI.Type,+    typesToDefine :: Seq (Ptr FFI.Type),+    metadataNodesToDefine :: Seq (A.MetadataNodeID, Ptr FFI.MDNode),+    metadataNodes :: Map (Ptr FFI.MDNode) A.MetadataNodeID,+    metadataKinds :: Array Word String,+    parameterAttributeSets :: Map FFI.ParameterAttributeSet [A.A.ParameterAttribute],+    functionAttributeSetIDs :: Map FFI.FunctionAttributeSet A.A.GroupID,+    comdats :: Map (Ptr FFI.COMDAT) (String, A.COMDAT.SelectionKind)+  }+initialDecode = DecodeState {+    globalVarNum = Map.empty,+    localVarNum = Map.empty,+    localNameCounter = Nothing,+    namedTypeNum = Map.empty,+    typesToDefine = Seq.empty,+    metadataNodesToDefine = Seq.empty,+    metadataNodes = Map.empty,+    metadataKinds = Array.listArray (1,0) [],+    parameterAttributeSets = Map.empty,+    functionAttributeSetIDs = Map.empty,+    comdats = Map.empty+  }+newtype DecodeAST a = DecodeAST { unDecodeAST :: AnyContT (StateT DecodeState IO) a }+  deriving (+    Applicative,+    Functor,+    Monad,+    MonadIO,+    MonadState DecodeState,+    MonadAnyCont IO,+    ScopeAnyCont+  )++runDecodeAST :: DecodeAST a -> IO a+runDecodeAST d = flip evalStateT initialDecode . flip runAnyContT return . unDecodeAST $ d++localScope :: DecodeAST a -> DecodeAST a+localScope (DecodeAST x) = DecodeAST (tweak x)+  where tweak x = do+          modify (\s@DecodeState { localNameCounter = Nothing } -> s { localNameCounter = Just 0 })+          r <- x+          modify (\s@DecodeState { localNameCounter = Just _ } -> s { localNameCounter = Nothing })+          return r++getName :: (Ptr a -> IO CString)+           -> Ptr a+           -> (DecodeState -> NameMap a)+           -> DecodeAST Word+           -> DecodeAST A.Name+getName getCString v getNameMap generate = do+  name <- liftIO $ do+            n <- getCString v+            if n == nullPtr then return "" else decodeM n+  if name /= "" +     then+       return $ A.Name name+     else+       A.UnName <$> do+         nm <- gets getNameMap+         maybe generate return $ Map.lookup v nm++getValueName :: FFI.DescendentOf FFI.Value v => Ptr v -> (DecodeState -> NameMap v) -> DecodeAST Word -> DecodeAST A.Name+getValueName = getName (FFI.getValueName . FFI.upCast)++getLocalName :: FFI.DescendentOf FFI.Value v => Ptr v -> DecodeAST A.Name+getLocalName v' = do+  let v = FFI.upCast v'+  getValueName v localVarNum $ do+                    nm <- gets localVarNum+                    Just n <- gets localNameCounter+                    modify $ \s -> s { localNameCounter = Just (1 + n), localVarNum = Map.insert v n nm }+                    return n++getGlobalName :: FFI.DescendentOf FFI.GlobalValue v => Ptr v -> DecodeAST A.Name+getGlobalName v' = do+  let v = FFI.upCast v'+  getValueName v globalVarNum $ do+                     nm <- gets globalVarNum+                     let n = fromIntegral $ Map.size nm+                     modify $ \s -> s { globalVarNum = Map.insert v n nm }+                     return n+++getTypeName :: Ptr FFI.Type -> DecodeAST A.Name+getTypeName t = do+  getName FFI.getStructName t namedTypeNum $ do+                  nm <- gets namedTypeNum+                  let n = fromIntegral $ Map.size nm+                  modify $ \s -> s { namedTypeNum = Map.insert t n nm }+                  return n++saveNamedType :: Ptr FFI.Type -> DecodeAST ()+saveNamedType t = do+  modify $ \s -> s { typesToDefine = t Seq.<| typesToDefine s }++getMetadataNodeID :: Ptr FFI.MDNode -> DecodeAST A.MetadataNodeID+getMetadataNodeID p = do+  mdns <- gets metadataNodes+  case Map.lookup p mdns of+    Just r -> return r+    Nothing -> do+      let r = A.MetadataNodeID (fromIntegral (Map.size mdns))+      modify $ \s -> s { +        metadataNodesToDefine = (r, p) Seq.<| metadataNodesToDefine s,+        metadataNodes = Map.insert p r (metadataNodes s)+      }+      return r++takeTypeToDefine :: DecodeAST (Maybe (Ptr FFI.Type))+takeTypeToDefine = state $ \s -> case Seq.viewr (typesToDefine s) of+  remaining Seq.:> t -> (Just t, s { typesToDefine = remaining })+  _ -> (Nothing, s)++takeMetadataNodeToDefine :: DecodeAST (Maybe (A.MetadataNodeID, Ptr FFI.MDNode))+takeMetadataNodeToDefine = state $ \s -> case Seq.viewr (metadataNodesToDefine s) of+  remaining Seq.:> md -> (Just md, s { metadataNodesToDefine = remaining })+  _ -> (Nothing, s)                              ++instance DecodeM DecodeAST A.Name (Ptr FFI.BasicBlock) where+  decodeM = getLocalName++getAttributeGroupID :: FFI.FunctionAttributeSet -> DecodeAST A.A.GroupID+getAttributeGroupID p = do+  ids <- gets functionAttributeSetIDs+  case Map.lookup p ids of+    Just r -> return r+    Nothing -> do+      let r = A.A.GroupID (fromIntegral (Map.size ids))+      modify $ \s -> s { functionAttributeSetIDs = Map.insert p r (functionAttributeSetIDs s) }+      return r
+ src/LLVM/Internal/Diagnostic.hs view
@@ -0,0 +1,40 @@+{-# LANGUAGE+  TemplateHaskell,+  MultiParamTypeClasses+  #-}  +module LLVM.Internal.Diagnostic where++import LLVM.Prelude++import qualified LLVM.Internal.FFI.LLVMCTypes as FFI+import qualified LLVM.Internal.FFI.SMDiagnostic as FFI++import Control.Exception++import Foreign.Ptr++import LLVM.Diagnostic+import LLVM.Internal.Coding+import LLVM.Internal.String ()++genCodingInstance [t| DiagnosticKind |] ''FFI.DiagnosticKind [+    (FFI.diagnosticKindError, ErrorKind),+    (FFI.diagnosticKindWarning, WarningKind),+    (FFI.diagnosticKindNote, NoteKind)+  ]++withSMDiagnostic :: (Ptr FFI.SMDiagnostic -> IO a) -> IO a+withSMDiagnostic = bracket FFI.createSMDiagnostic FFI.disposeSMDiagnostic++getDiagnostic :: Ptr FFI.SMDiagnostic -> IO Diagnostic+getDiagnostic p = do+  l <- decodeM =<< FFI.getSMDiagnosticLineNo p+  c <- decodeM =<< FFI.getSMDiagnosticColumnNo p+  k <- decodeM =<< FFI.getSMDiagnosticKind p+  f <- decodeM $ FFI.getSMDiagnosticFilename p+  m <- decodeM $ FFI.getSMDiagnosticMessage p+  lc <- decodeM $ FFI.getSMDiagnosticLineContents p+  return $ Diagnostic { +    lineNumber = l, columnNumber = c, diagnosticKind = k, filename = f, message = m, lineContents = lc+   }+
+ src/LLVM/Internal/EncodeAST.hs view
@@ -0,0 +1,159 @@+{-# LANGUAGE+  GeneralizedNewtypeDeriving,+  MultiParamTypeClasses,+  UndecidableInstances+  #-}+module LLVM.Internal.EncodeAST where++import LLVM.Prelude++import Control.Exception+import Control.Monad.AnyCont+import Control.Monad.Error.Class+import Control.Monad.State+import Control.Monad.Trans.Except++import Foreign.Ptr+import Foreign.C++import Data.Map (Map)+import qualified Data.Map as Map++import qualified LLVM.Internal.FFI.Attribute as FFI  +import qualified LLVM.Internal.FFI.Builder as FFI+import qualified LLVM.Internal.FFI.GlobalValue as FFI+import qualified LLVM.Internal.FFI.PtrHierarchy as FFI+import qualified LLVM.Internal.FFI.Value as FFI++import qualified LLVM.AST as A+import qualified LLVM.AST.Attribute as A.A++import LLVM.Internal.Context+import LLVM.Internal.Coding+import LLVM.Internal.String ()++data LocalValue+  = ForwardValue (Ptr FFI.Value)+  | DefinedValue (Ptr FFI.Value)++data EncodeState = EncodeState {+      encodeStateBuilder :: Ptr FFI.Builder,+      encodeStateContext :: Context,+      encodeStateLocals :: Map A.Name LocalValue,+      encodeStateGlobals :: Map A.Name (Ptr FFI.GlobalValue),+      encodeStateAllBlocks :: Map (A.Name, A.Name) (Ptr FFI.BasicBlock),+      encodeStateBlocks :: Map A.Name (Ptr FFI.BasicBlock),+      encodeStateMDNodes :: Map A.MetadataNodeID (Ptr FFI.MDNode),+      encodeStateNamedTypes :: Map A.Name (Ptr FFI.Type),+      encodeStateAttributeGroups :: Map A.A.GroupID FFI.FunctionAttributeSet,+      encodeStateCOMDATs :: Map String (Ptr FFI.COMDAT)+    }++newtype EncodeAST a = EncodeAST { unEncodeAST :: AnyContT (ExceptT String (StateT EncodeState IO)) a }+    deriving (+       Functor,+       Applicative,+       Monad,+       MonadIO,+       MonadState EncodeState,+       MonadError String,+       MonadAnyCont IO,+       ScopeAnyCont+     )++lookupNamedType :: A.Name -> EncodeAST (Ptr FFI.Type)+lookupNamedType n = do+  t <- gets $ Map.lookup n . encodeStateNamedTypes+  maybe (throwError $ "reference to undefined type: " ++ show n) return t++defineType :: A.Name -> Ptr FFI.Type -> EncodeAST ()+defineType n t = modify $ \s -> s { encodeStateNamedTypes = Map.insert n t (encodeStateNamedTypes s) }++runEncodeAST :: Context -> EncodeAST a -> ExceptT String IO a+runEncodeAST context@(Context ctx) (EncodeAST a) = ExceptT $+    bracket (FFI.createBuilderInContext ctx) FFI.disposeBuilder $ \builder -> do+      let initEncodeState = EncodeState {+              encodeStateBuilder = builder,+              encodeStateContext = context,+              encodeStateLocals = Map.empty,+              encodeStateGlobals = Map.empty,+              encodeStateAllBlocks = Map.empty,+              encodeStateBlocks = Map.empty,+              encodeStateMDNodes = Map.empty,+              encodeStateNamedTypes = Map.empty,+              encodeStateAttributeGroups = Map.empty,+              encodeStateCOMDATs = Map.empty+            }+      flip evalStateT initEncodeState . runExceptT . flip runAnyContT return $ a++withName :: A.Name -> (CString -> IO a) -> IO a+withName (A.Name n) = withCString n+withName (A.UnName _) = withCString ""++instance MonadAnyCont IO m => EncodeM m A.Name CString where+  encodeM (A.Name n) = encodeM n+  encodeM _ = encodeM ""++phase :: EncodeAST a -> EncodeAST (EncodeAST a)+phase p = do+  let s0 `withLocalsFrom` s1 = s0 {+         encodeStateLocals = encodeStateLocals s1,+         encodeStateBlocks = encodeStateBlocks s1+        }+  s <- get+  return $ do+    s' <- get+    put $ s' `withLocalsFrom` s+    r <- p+    modify (`withLocalsFrom` s')+    return r++defineLocal :: FFI.DescendentOf FFI.Value v => A.Name -> Ptr v -> EncodeAST ()+defineLocal n v' = do+  let v = FFI.upCast v'+  def <- gets $ Map.lookup n . encodeStateLocals+  case def of+    Just (ForwardValue dummy) -> liftIO $ FFI.replaceAllUsesWith dummy v+    _ -> return ()+  modify $ \b -> b { encodeStateLocals = Map.insert n (DefinedValue v) (encodeStateLocals b) }++defineGlobal :: FFI.DescendentOf FFI.GlobalValue v => A.Name -> Ptr v -> EncodeAST ()+defineGlobal n v = modify $ \b -> b { encodeStateGlobals =  Map.insert n (FFI.upCast v) (encodeStateGlobals b) }++defineMDNode :: A.MetadataNodeID -> Ptr FFI.MDNode -> EncodeAST ()+defineMDNode n v = modify $ \b -> b { encodeStateMDNodes = Map.insert n (FFI.upCast v) (encodeStateMDNodes b) }++defineAttributeGroup :: A.A.GroupID -> FFI.FunctionAttributeSet -> EncodeAST ()+defineAttributeGroup gid attrs = modify $ \b -> b { encodeStateAttributeGroups = Map.insert gid attrs (encodeStateAttributeGroups b) }++defineCOMDAT :: String -> Ptr FFI.COMDAT -> EncodeAST ()+defineCOMDAT name cd = modify $ \b -> b { encodeStateCOMDATs = Map.insert name cd (encodeStateCOMDATs b) }++refer :: (Show n, Ord n) => (EncodeState -> Map n v) -> n -> EncodeAST v -> EncodeAST v+refer r n f = do+  mop <- gets $ Map.lookup n . r+  maybe f return mop++undefinedReference :: Show n => String -> n -> EncodeAST a+undefinedReference m n = throwError $ "reference to undefined " ++ m ++ ": " ++ show n++referOrThrow :: (Show n, Ord n) => (EncodeState -> Map n v) -> String -> n -> EncodeAST v+referOrThrow r m n = refer r n $ undefinedReference m n++referGlobal = referOrThrow encodeStateGlobals "global"+referMDNode = referOrThrow encodeStateMDNodes "metadata node"+referAttributeGroup = referOrThrow encodeStateAttributeGroups "attribute group"+referCOMDAT = referOrThrow encodeStateCOMDATs "COMDAT"++defineBasicBlock :: A.Name -> A.Name -> Ptr FFI.BasicBlock -> EncodeAST ()+defineBasicBlock fn n b = modify $ \s -> s {+  encodeStateBlocks = Map.insert n b (encodeStateBlocks s),+  encodeStateAllBlocks = Map.insert (fn, n) b (encodeStateAllBlocks s)+}++instance EncodeM EncodeAST A.Name (Ptr FFI.BasicBlock) where+  encodeM = referOrThrow encodeStateBlocks "block"++getBlockForAddress :: A.Name -> A.Name -> EncodeAST (Ptr FFI.BasicBlock)+getBlockForAddress fn n = referOrThrow encodeStateAllBlocks "blockaddress" (fn, n)+
+ src/LLVM/Internal/ExecutionEngine.hs view
@@ -0,0 +1,134 @@+{-# LANGUAGE+  MultiParamTypeClasses,+  FunctionalDependencies,+  RankNTypes+  #-}+module LLVM.Internal.ExecutionEngine where++import LLVM.Prelude++import Control.Exception+import Control.Monad.IO.Class+import Control.Monad.AnyCont+import Control.Monad.Trans.Except++import Data.IORef+import Foreign.Ptr+import Foreign.C (CUInt, CString)+import Foreign.Marshal.Alloc (allocaBytes)++import qualified LLVM.Internal.FFI.PtrHierarchy as FFI+import qualified LLVM.Internal.FFI.ExecutionEngine as FFI+import qualified LLVM.Internal.FFI.Module as FFI+import qualified LLVM.Internal.FFI.LLVMCTypes as FFI++import LLVM.Internal.Module+import LLVM.Internal.Context+import LLVM.Internal.Coding+import qualified LLVM.CodeModel as CodeModel+import LLVM.Internal.Target+import qualified LLVM.AST as A++removeModule :: Ptr FFI.ExecutionEngine -> Ptr FFI.Module -> IO ()+removeModule e m = flip runAnyContT return $ do+  d0 <- alloca+  d1 <- alloca+  r <- liftIO $ FFI.removeModule e m d0 d1+  when (r /= 0) $ fail "FFI.removeModule failure"++-- | a 'ExecutableModule' e represents a 'Module' which is currently "in" an+-- 'ExecutionEngine', and so the functions of which may be executed.+data ExecutableModule e = ExecutableModule e (Ptr FFI.Module)++-- | <http://llvm.org/doxygen/classllvm_1_1ExecutionEngine.html>+class ExecutionEngine e f | e -> f where+  withModuleInEngine :: e -> Module -> (ExecutableModule e -> IO a) -> IO a+  getFunction :: ExecutableModule e -> A.Name -> IO (Maybe f)++instance ExecutionEngine (Ptr FFI.ExecutionEngine) (FunPtr ()) where+  withModuleInEngine e m f = do+    m' <- readModule m+    bracket_ (FFI.addModule e m') (removeModule e m') (f (ExecutableModule e m'))+  getFunction (ExecutableModule e m) (A.Name name) = flip runAnyContT return $ do+    name <- encodeM name+    f <- liftIO $ FFI.getNamedFunction m name+    if f == nullPtr +      then +        return Nothing+      else+        do+          p <- liftIO $ FFI.getPointerToGlobal e (FFI.upCast f)+          return $ if p == nullPtr then Nothing else Just (castPtrToFunPtr p)++withExecutionEngine :: +  Context ->+  Maybe (Ptr FFI.Module) -> +  (Ptr (Ptr FFI.ExecutionEngine) -> Ptr FFI.Module -> Ptr (FFI.OwnerTransfered CString) -> IO CUInt) ->+  (Ptr FFI.ExecutionEngine -> IO a) ->+  IO a+withExecutionEngine c m createEngine f = flip runAnyContT return $ do+  liftIO initializeNativeTarget+  outExecutionEngine <- alloca+  outErrorCStringPtr <- alloca+  dummyModule <- maybe (anyContToM $ liftM (either undefined id) . runExceptT+                            . withModuleFromAST c (A.Module "" "" Nothing Nothing []))+                 (liftIO . newModule) m+  dummyModule' <- readModule dummyModule+  r <- liftIO $ createEngine outExecutionEngine dummyModule' outErrorCStringPtr+  when (r /= 0) $ fail =<< decodeM outErrorCStringPtr+  executionEngine <- anyContToM $ bracket (peek outExecutionEngine) FFI.disposeExecutionEngine+  liftIO $ removeModule executionEngine dummyModule'+  liftIO $ f executionEngine++data MCJITState+  = Deferred (forall a . Module -> (Ptr FFI.ExecutionEngine -> IO a) -> IO a)+  | Constructed (Ptr FFI.ExecutionEngine)++-- | <http://llvm.org/doxygen/classllvm_1_1MCJIT.html>+-- <http://blog.llvm.org/2010/04/intro-to-llvm-mc-project.html>+-- N.B. - the LLVM MCJIT does not current support adding multiple+-- modules to any one instance of the MCJIT.+newtype MCJIT = MCJIT (IORef MCJITState)++-- | bracket the creation and destruction of an 'MCJIT'+withMCJIT :: +  Context+  -> Maybe Word -- ^ optimization level+  -> Maybe CodeModel.Model+  -> Maybe Bool -- ^ True to disable frame pointer elimination+  -> Maybe Bool -- ^ True to enable fast instruction selection+--  -> Maybe MemoryManager -- llvm-hs doesn't support this yet+  -> (MCJIT -> IO a)+  -> IO a+withMCJIT c opt cm fpe fisel f = do+  FFI.linkInMCJIT+  let createMCJITCompilerForModule e m s = do+        size <- FFI.getMCJITCompilerOptionsSize+        allocaBytes (fromIntegral size) $ \p -> do+          FFI.initializeMCJITCompilerOptions p size+          maybe (return ()) (FFI.setMCJITCompilerOptionsOptLevel p <=< encodeM) opt+          maybe (return ()) (FFI.setMCJITCompilerOptionsCodeModel p <=< encodeM) cm+          maybe (return ()) (FFI.setMCJITCompilerOptionsNoFramePointerElim p <=< encodeM) fpe+          maybe (return ()) (FFI.setMCJITCompilerOptionsEnableFastISel p <=< encodeM) fisel+          FFI.createMCJITCompilerForModule e m p size s+  t <- newIORef (Deferred $ \mod f -> do m' <- readModule mod+                                         withExecutionEngine c (Just m') createMCJITCompilerForModule f)+  f (MCJIT t)++instance ExecutionEngine MCJIT (FunPtr ()) where+  withModuleInEngine (MCJIT s) m f = do+    jitState <- readIORef s+    let f' (ExecutableModule _ m) = f (ExecutableModule (MCJIT s) m)+    case jitState of+      Deferred c -> c m $ \e -> +        bracket_ +         (writeIORef s (Constructed e))+         (writeIORef s jitState)+         (withModuleInEngine e m f')+      Constructed e -> withModuleInEngine e m f'++  getFunction (ExecutableModule (MCJIT r) m) n = do+    s <- liftIO $ readIORef r+    case s of+      Deferred _ -> return Nothing+      Constructed e -> getFunction (ExecutableModule e m) n
+ src/LLVM/Internal/FFI/Analysis.h view
@@ -0,0 +1,11 @@+#ifndef __LLVM_INTERNAL_FFI__ANALYSIS__H__+#define __LLVM_INTERNAL_FFI__ANALYSIS__H__++#include "llvm-c/Analysis.h"++#define LLVM_HS_FOR_EACH_VERIFIER_FAILURE_ACTION(macro) \+	macro(AbortProcess) \+	macro(PrintMessage) \+	macro(ReturnStatus)++#endif
+ src/LLVM/Internal/FFI/Analysis.hs view
@@ -0,0 +1,15 @@+{-# LANGUAGE+  ForeignFunctionInterface+  #-}+module LLVM.Internal.FFI.Analysis where++import LLVM.Prelude++import Foreign.Ptr+import Foreign.C++import LLVM.Internal.FFI.LLVMCTypes+import LLVM.Internal.FFI.Module++foreign import ccall unsafe "LLVMVerifyModule" verifyModule ::+  Ptr Module -> VerifierFailureAction -> Ptr (OwnerTransfered CString) -> IO LLVMBool
+ src/LLVM/Internal/FFI/Assembly.hs view
@@ -0,0 +1,29 @@+{-# LANGUAGE+  ForeignFunctionInterface+  #-}++-- | Functions to read and write textual LLVM assembly+module LLVM.Internal.FFI.Assembly where++import LLVM.Prelude++import LLVM.Internal.FFI.Context+import LLVM.Internal.FFI.LLVMCTypes+import LLVM.Internal.FFI.MemoryBuffer+import LLVM.Internal.FFI.Module+import LLVM.Internal.FFI.PtrHierarchy++import Foreign.C+import Foreign.Ptr++-- | Use LLVM's parser to parse a string of llvm assembly in a memory buffer to get a module+foreign import ccall unsafe "LLVM_Hs_ParseLLVMAssembly" parseLLVMAssembly ::+  Ptr Context -> OwnerTransfered (Ptr MemoryBuffer) -> Ptr (OwnerTransfered CString) -> IO (Ptr Module)+++-- | LLVM's serializer to generate a string of llvm assembly from a module+foreign import ccall unsafe "LLVM_Hs_WriteLLVMAssembly" writeLLVMAssembly ::+  Ptr Module -> Ptr RawOStream -> IO ()+++
+ src/LLVM/Internal/FFI/AssemblyC.cpp view
@@ -0,0 +1,28 @@+#define __STDC_LIMIT_MACROS+#include "llvm/AsmParser/Parser.h"+#include "llvm/IR/LLVMContext.h"+#include "llvm/IR/Module.h"+#include "llvm/Pass.h"+#include "llvm/Support/MemoryBuffer.h"+#include "llvm/Support/SourceMgr.h"+#include "llvm/Support/raw_ostream.h"++#include "llvm-c/Core.h"+#include "llvm-c/IRReader.h"++using namespace llvm;++extern "C" {++LLVMModuleRef LLVM_Hs_ParseLLVMAssembly(LLVMContextRef context,+                                             LLVMMemoryBufferRef memoryBuffer,+                                             char **error) {+  LLVMModuleRef M;+  LLVMParseIRInContext(context, memoryBuffer, &M, error);+  return M;+}++void LLVM_Hs_WriteLLVMAssembly(LLVMModuleRef module, raw_ostream &os) {+  os << *unwrap(module);+}+}
+ src/LLVM/Internal/FFI/Attribute.h view
@@ -0,0 +1,69 @@+#ifndef __LLVM_INTERNAL_FFI__ATTRIBUTES__H__+#define __LLVM_INTERNAL_FFI__ATTRIBUTES__H__+++// The last three arguments are flags indicating if this is a+// parameter attribute, function result attribute or function attribute.+#define LLVM_HS_FOR_EACH_ATTRIBUTE_KIND(macro)	\+	macro(None,F,F,F)                                 \+	macro(Alignment,T,T,F)                            \+	macro(AllocSize,F,F,T)                            \+	macro(AlwaysInline,F,F,T)                         \+	macro(ArgMemOnly,F,F,T)                           \+	macro(Builtin,F,F,T)                              \+	macro(ByVal,T,F,F)                                \+	macro(Cold,F,F,T)                                 \+	macro(Convergent,F,F,T)                           \+	macro(Dereferenceable,T,T,F)                      \+	macro(DereferenceableOrNull,T,T,F)                \+	macro(InAlloca,T,F,F)                             \+	macro(InReg,T,T,F)                                \+	macro(InaccessibleMemOnly,F,F,T) \+	macro(InaccessibleMemOrArgMemOnly,F,F,T) \+	macro(InlineHint,F,F,T)                           \+	macro(JumpTable,F,F,T)                            \+	macro(MinSize,F,F,T)                              \+	macro(Naked,F,F,T)                                \+	macro(Nest,T,F,F)                                 \+	macro(NoAlias,T,T,F)                              \+	macro(NoBuiltin,F,F,T)                            \+	macro(NoCapture,T,F,F)                            \+	macro(NoDuplicate,F,F,T)                          \+	macro(NoImplicitFloat,F,F,T)                      \+	macro(NoInline,F,F,T)                             \+	macro(NoRecurse,F,F,T)                            \+	macro(NoRedZone,F,F,T)                            \+	macro(NoReturn,F,F,T)                             \+	macro(NoUnwind,F,F,T)                             \+	macro(NonLazyBind,F,F,T)                          \+	macro(NonNull,T,T,F)                              \+	macro(OptimizeForSize,F,F,T)                      \+	macro(OptimizeNone,F,F,T)                         \+	macro(ReadNone,T,F,T)                             \+	macro(ReadOnly,T,F,T)                             \+	macro(Returned,T,F,F)                             \+	macro(ReturnsTwice,F,F,T)                         \+	macro(SExt,T,T,F)                                 \+	macro(SafeStack,F,F,T)                            \+	macro(SanitizeAddress,F,F,T)                      \+	macro(SanitizeMemory,F,F,T)                       \+	macro(SanitizeThread,F,F,T)                       \+	macro(StackAlignment,F,F,T)                       \+	macro(StackProtect,F,F,T)                         \+	macro(StackProtectReq,F,F,T)                      \+	macro(StackProtectStrong,F,F,T)                   \+	macro(StructRet,T,F,F)                            \+	macro(SwiftError,T,F,F)                           \+	macro(SwiftSelf,T,F,F)                            \+	macro(UWTable,F,F,T)                              \+	macro(WriteOnly,T,F,T)                            \+	macro(ZExt,T,T,F)                                 \+	macro(EndAttrKinds,F,F,F)++typedef enum {+#define ENUM_CASE(x,p,r,f) LLVM_Hs_AttributeKind_ ## x,+LLVM_HS_FOR_EACH_ATTRIBUTE_KIND(ENUM_CASE)+#undef ENUM_CASE+} LLVM_Hs_AttributeKind;++#endif
+ src/LLVM/Internal/FFI/Attribute.hs view
@@ -0,0 +1,143 @@+{-# LANGUAGE+  ForeignFunctionInterface+  #-}+module LLVM.Internal.FFI.Attribute where++import LLVM.Prelude++import Foreign.C+import Foreign.Ptr++import LLVM.Internal.FFI.Context+import LLVM.Internal.FFI.LLVMCTypes++type Index = CInt+type Slot = CUInt+type IntValue = Word64++{-+Data model:+llvm::Attribute is one function or parameter attribute++llvm::AttributeSet is a mess.+It's used to represent, at different times:+a) the set of parameter attributes on a parameter+b) the set of parameter attributes for a functions return value+c) the set of function attributes for a function+d) All of the above++It is only possible to enumerate the attributes in an attribute set+given a "slot".++Encode path:+Use AttrBuilder on the C++ side only, to implement [Attribute] -> AttributeSet+AttributeSets -> whole AttributeSet++Decode strategy:+Store maps of AttributeSetImpl (Mess | Parameter | Function),+keyed by raw pointer. Expect Parameter and Function AttributeSetImpls+to have only one slot. Use the per-slot iterators to decode them+-}++data MixedAttributeType+data FunctionAttributeType+data ParameterAttributeType+data AttributeImpl a+data AttributeSetImpl a++type Attribute a = Ptr (AttributeImpl a)+type FunctionAttribute = Attribute FunctionAttributeType+type ParameterAttribute = Attribute ParameterAttributeType++type AttributeSet a = Ptr (AttributeSetImpl a)+type MixedAttributeSet = AttributeSet MixedAttributeType+type FunctionAttributeSet = AttributeSet FunctionAttributeType+type ParameterAttributeSet = AttributeSet ParameterAttributeType++forgetAttributeType :: AttributeSet a -> AttributeSet MixedAttributeType+forgetAttributeType = castPtr++functionIndex :: Index+functionIndex = -1+returnIndex :: Index+returnIndex = 0++foreign import ccall unsafe "LLVM_Hs_AttributeKindAsEnum" parameterAttributeKindAsEnum ::+  ParameterAttribute -> IO ParameterAttributeKind++foreign import ccall unsafe "LLVM_Hs_AttributeKindAsEnum" functionAttributeKindAsEnum ::+  FunctionAttribute -> IO FunctionAttributeKind++foreign import ccall unsafe "LLVM_Hs_IsStringAttribute" isStringAttribute ::+  Attribute a -> IO LLVMBool++foreign import ccall unsafe "LLVM_Hs_AttributeKindAsString" attributeKindAsString ::+  Attribute a -> Ptr CSize -> IO (Ptr CChar)++foreign import ccall unsafe "LLVM_Hs_AttributeValueAsString" attributeValueAsString ::+  Attribute a -> Ptr CSize -> IO (Ptr CChar)++foreign import ccall unsafe "LLVM_Hs_AttributeValueAsInt" attributeValueAsInt ::+  Attribute a -> IO Word64++foreign import ccall unsafe "LLVM_Hs_AttributeSetNumSlots" attributeSetNumSlots ::+  AttributeSet a -> IO Slot++foreign import ccall unsafe "LLVM_Hs_AttributeSetSlotIndex" attributeSetSlotIndex ::+  AttributeSet a -> Slot -> IO Index++foreign import ccall unsafe "LLVM_Hs_AttributeSetSlotAttributes" attributeSetSlotAttributes ::+  MixedAttributeSet -> Slot -> IO (AttributeSet a)++foreign import ccall unsafe "LLVM_Hs_AttributeSetGetAttributes" attributeSetGetAttributes ::+  AttributeSet a -> Slot -> Ptr CUInt -> IO (Ptr (Attribute a))++foreign import ccall unsafe "LLVM_Hs_GetAttributeSet" getAttributeSet ::+  Ptr Context -> Index -> Ptr (AttrBuilder a) -> IO (AttributeSet a)++foreign import ccall unsafe "LLVM_Hs_MixAttributeSets" mixAttributeSets ::+  Ptr Context -> Ptr MixedAttributeSet -> CUInt -> IO MixedAttributeSet++data AttrBuilder a+type FunctionAttrBuilder = AttrBuilder FunctionAttributeType+type ParameterAttrBuilder = AttrBuilder ParameterAttributeType++foreign import ccall unsafe "LLVM_Hs_GetAttrBuilderSize" getAttrBuilderSize ::+  CSize++foreign import ccall unsafe "LLVM_Hs_ConstructAttrBuilder" constructAttrBuilder ::+  Ptr Word8 -> IO (Ptr (AttrBuilder a))++foreign import ccall unsafe "LLVM_Hs_DestroyAttrBuilder" destroyAttrBuilder ::+  Ptr (AttrBuilder a) -> IO ()++foreign import ccall unsafe "LLVM_Hs_AttrBuilderAddAttributeKind" attrBuilderAddFunctionAttributeKind ::+  Ptr FunctionAttrBuilder -> FunctionAttributeKind -> IO ()++foreign import ccall unsafe "LLVM_Hs_AttrBuilderAddAttributeKind" attrBuilderAddParameterAttributeKind ::+  Ptr ParameterAttrBuilder -> ParameterAttributeKind -> IO ()++foreign import ccall unsafe "LLVM_Hs_AttrBuilderAddStringAttribute" attrBuilderAddStringAttribute ::+  Ptr FunctionAttrBuilder -> Ptr CChar -> CSize -> Ptr CChar -> CSize -> IO ()++foreign import ccall unsafe "LLVM_Hs_AttrBuilderAddAlignment" attrBuilderAddAlignment ::+  Ptr ParameterAttrBuilder -> Word64 -> IO ()++foreign import ccall unsafe "LLVM_Hs_AttrBuilderAddStackAlignment" attrBuilderAddStackAlignment ::+  Ptr FunctionAttrBuilder -> Word64 -> IO ()++-- The CInt is 0 if the last value is null and 1 otherwise+foreign import ccall unsafe "LLVM_Hs_AttrBuilderAddAllocSize" attrBuilderAddAllocSize' ::+  Ptr FunctionAttrBuilder -> CUInt -> CUInt -> LLVMBool -> IO ()++attrBuilderAddAllocSize :: Ptr FunctionAttrBuilder -> CUInt -> (CUInt, LLVMBool) -> IO ()+attrBuilderAddAllocSize b i (y, isJust) = attrBuilderAddAllocSize' b i y isJust++foreign import ccall unsafe "LLVM_Hs_AttrBuilderAddDereferenceableAttr" attrBuilderAddDereferenceable ::+  Ptr ParameterAttrBuilder -> Word64 -> IO ()++foreign import ccall unsafe "LLVM_Hs_AttrBuilderAddDereferenceableOrNullAttr" attrBuilderAddDereferenceableOrNull ::+  Ptr ParameterAttrBuilder -> Word64 -> IO ()++foreign import ccall unsafe "LLVM_Hs_AttributeGetAllocSizeArgs" attributeGetAllocSizeArgs ::+  FunctionAttribute -> Ptr CUInt -> Ptr CUInt -> IO LLVMBool
+ src/LLVM/Internal/FFI/AttributeC.cpp view
@@ -0,0 +1,145 @@+#define __STDC_LIMIT_MACROS+#include "llvm/IR/LLVMContext.h"+#include "LLVM/Internal/FFI/AttributeC.hpp"++extern "C" {++static_assert(sizeof(AttributeSet) == sizeof(AttributeSetImpl *),+              "AttributeSet implementation has changed");++static_assert(sizeof(Attribute) == sizeof(AttributeImpl *),+              "Attribute implementation has changed");++unsigned LLVM_Hs_AttributeSetNumSlots(const AttributeSetImpl *a) {+	return unwrap(a).getNumSlots();+}++int LLVM_Hs_AttributeSetSlotIndex(const AttributeSetImpl *a, unsigned slot) {+	return unwrap(a).getSlotIndex(slot);+}++const AttributeSetImpl *LLVM_Hs_AttributeSetSlotAttributes(const AttributeSetImpl *a, unsigned slot) {+	return wrap(unwrap(a).getSlotAttributes(slot));+}++const AttributeSetImpl *LLVM_Hs_GetSlotAttributeSet(+	LLVMContextRef context,+	unsigned index,+	const AttributeImpl **attributes,+	unsigned length+) {+	AttrBuilder builder;+	for (unsigned i = 0; i < length; i++) builder.addAttribute(unwrap(attributes[i]));+	return wrap(AttributeSet::get(*unwrap(context), index, builder));+}++const AttributeImpl *const *LLVM_Hs_AttributeSetGetAttributes(AttributeSetImpl *asi, unsigned slot, unsigned *length) {+	AttributeSet as = unwrap(asi);+	ArrayRef<Attribute>::iterator b = as.begin(slot), e = as.end(slot);+	*length = e - b;+	return reinterpret_cast<const AttributeImpl *const *>(b);+}++#define CHECK(name,p,r,f)																								\+	static_assert(																												\+		unsigned(llvm::Attribute::name) == unsigned(LLVM_Hs_AttributeKind_ ## name), \+		"LLVM_Hs_AttributeKind enum out of sync w/ llvm::Attribute::AttrKind for " #name	\+	);+	LLVM_HS_FOR_EACH_ATTRIBUTE_KIND(CHECK)+#undef CHECK++unsigned LLVM_Hs_AttributeKindAsEnum(const AttributeImpl *a) {+    return unwrap(a).getKindAsEnum();+}++uint64_t LLVM_Hs_AttributeValueAsInt(const AttributeImpl *a) {+	return unwrap(a).getValueAsInt();+}++LLVMBool LLVM_Hs_IsStringAttribute(const AttributeImpl *a) {+	return unwrap(a).isStringAttribute();+}++const char *LLVM_Hs_AttributeKindAsString(const AttributeImpl *a, size_t &l) {+	const StringRef s = unwrap(a).getKindAsString();+	l = s.size();+	return s.data();+}++const char *LLVM_Hs_AttributeValueAsString(const AttributeImpl *a, size_t &l) {+	const StringRef s = unwrap(a).getValueAsString();+	l = s.size();+	return s.data();+}++const AttributeSetImpl *LLVM_Hs_GetAttributeSet(LLVMContextRef context, unsigned index, const AttrBuilder &ab) {+	return wrap(AttributeSet::get(*unwrap(context), index, ab));+}++const AttributeSetImpl *LLVM_Hs_MixAttributeSets(+	LLVMContextRef context, const AttributeSetImpl **as, unsigned n+) {+	return wrap(+		AttributeSet::get(+			*unwrap(context),+			ArrayRef<AttributeSet>(reinterpret_cast<const AttributeSet *>(as), n)+		)+	);+}++size_t LLVM_Hs_GetAttrBuilderSize() { return sizeof(AttrBuilder); }++AttrBuilder *LLVM_Hs_ConstructAttrBuilder(char *p) {+	return new(p) AttrBuilder();+}++void LLVM_Hs_DestroyAttrBuilder(AttrBuilder *a) {+	a->~AttrBuilder();+}++void LLVM_Hs_AttrBuilderAddAttributeKind(AttrBuilder &ab, unsigned kind) {+    ab.addAttribute(Attribute::AttrKind(kind));+}++void LLVM_Hs_AttrBuilderAddStringAttribute(+	AttrBuilder &ab, const char *kind, size_t kind_len, const char *value, size_t value_len+) {+	ab.addAttribute(StringRef(kind, kind_len), StringRef(value, value_len));+}++void LLVM_Hs_AttrBuilderAddAlignment(AttrBuilder &ab, uint64_t v) {+	ab.addAlignmentAttr(v);+}++void LLVM_Hs_AttrBuilderAddStackAlignment(AttrBuilder &ab, uint64_t v) {+	ab.addStackAlignmentAttr(v);+}++void LLVM_Hs_AttrBuilderAddAllocSize(AttrBuilder &ab, unsigned x, LLVMBool optionalIsThere, unsigned y) {+    if (optionalIsThere) {+        ab.addAllocSizeAttr(x, y);+    } else {+        ab.addAllocSizeAttr(x, Optional<unsigned>());+    }+}++void LLVM_Hs_AttrBuilderAddDereferenceableAttr(AttrBuilder &ab, uint64_t v) {+	ab.addDereferenceableAttr(v);+}++void LLVM_Hs_AttrBuilderAddDereferenceableOrNullAttr(AttrBuilder &ab, uint64_t v) {+    ab.addDereferenceableOrNullAttr(v);+}++LLVMBool LLVM_Hs_AttributeGetAllocSizeArgs(const AttributeImpl* a, unsigned* x, unsigned* y) {+    auto pair = unwrap(a).getAllocSizeArgs();+    *x = pair.first;+    if (pair.second.hasValue()) {+        *y = pair.second.getValue();+        return 1;+    } else {+        return 0;+    }+}++}
+ src/LLVM/Internal/FFI/AttributeC.hpp view
@@ -0,0 +1,24 @@+#ifndef __LLVM_ATTRIBUTE_C_HPP__+#define __LLVM_ATTRIBUTE_C_HPP__+#define __STDC_LIMIT_MACROS+#include "llvm/IR/Attributes.h"+#include "LLVM/Internal/FFI/Attribute.h"+using namespace llvm;++inline AttributeSet unwrap(const AttributeSetImpl *asi) {+    return *reinterpret_cast<const AttributeSet *>(&asi);+}++inline const AttributeSetImpl *wrap(AttributeSet as) {+    return *reinterpret_cast<const AttributeSetImpl **>(&as);+}++inline Attribute unwrap(const AttributeImpl *ai) {+    return *reinterpret_cast<const Attribute *>(&ai);+}++inline const AttributeImpl *wrap(Attribute a) {+    return *reinterpret_cast<const AttributeImpl **>(&a);+}++#endif
+ src/LLVM/Internal/FFI/BasicBlock.hs view
@@ -0,0 +1,34 @@+{-# LANGUAGE+  ForeignFunctionInterface,+  MultiParamTypeClasses+  #-}++-- | <http://llvm.org/doxygen/classllvm_1_1BasicBlock.html>+module LLVM.Internal.FFI.BasicBlock where++import LLVM.Prelude++import Foreign.Ptr++import LLVM.Internal.FFI.PtrHierarchy++-- | <http://llvm.org/doxygen/group__LLVMCCoreValueBasicBlock.html#gab57c996ff697ef40966432055ae47a4e>+foreign import ccall unsafe "LLVMIsABasicBlock" isABasicBlock ::+    Ptr Value -> IO (Ptr BasicBlock)++-- | <http://llvm.org/doxygen/group__LLVMCCoreValueBasicBlock.html#ga754e45f69f4b784b658d9e379943f354>+foreign import ccall unsafe "LLVMGetBasicBlockTerminator" getBasicBlockTerminator ::+    Ptr BasicBlock -> IO (Ptr Instruction)++-- | <http://llvm.org/doxygen/group__LLVMCCoreValueBasicBlock.html#ga9baf824cd325ad211027b23fce8a7494>+foreign import ccall unsafe "LLVMGetFirstInstruction" getFirstInstruction ::+    Ptr BasicBlock -> IO (Ptr Instruction)++-- | <http://llvm.org/doxygen/group__LLVMCCoreValueBasicBlock.html#gaa0bb2c95802d06bf94f4c55e61fc3477>+foreign import ccall unsafe "LLVMGetLastInstruction" getLastInstruction ::+    Ptr BasicBlock -> IO (Ptr Instruction)++-- | <http://llvm.org/doxygen/group__LLVMCCoreValueInstruction.html#ga1b4c3bd197e86e8bffdda247ddf8ec5e>+foreign import ccall unsafe "LLVMGetNextInstruction" getNextInstruction ::+    Ptr Instruction -> IO (Ptr Instruction)+
+ src/LLVM/Internal/FFI/BinaryOperator.h view
@@ -0,0 +1,16 @@+#ifndef __LLVM_INTERNAL_FFI__BINARY_OPERATOR__H__+#define __LLVM_INTERNAL_FFI__BINARY_OPERATOR__H__++#define LLVM_HS_FOR_EACH_POSSIBLY_EXACT_BINARY_OPERATOR(macro) \+	macro(UDiv) \+	macro(SDiv) \+	macro(LShr) \+	macro(AShr)++#define LLVM_HS_FOR_EACH_OVERFLOWING_BINARY_OPERATOR(macro) \+	macro(Add) \+	macro(Mul) \+	macro(Shl) \+	macro(Sub) \++#endif
+ src/LLVM/Internal/FFI/BinaryOperator.hs view
@@ -0,0 +1,30 @@+{-# LANGUAGE+  ForeignFunctionInterface,+  MultiParamTypeClasses,+  UndecidableInstances+  #-}+-- | FFI functions for handling the LLVM BinaryOperator class+module LLVM.Internal.FFI.BinaryOperator where++import LLVM.Prelude++import Foreign.Ptr+import Foreign.C++import LLVM.Internal.FFI.PtrHierarchy+import LLVM.Internal.FFI.LLVMCTypes++foreign import ccall unsafe "LLVMIsABinaryOperator" isABinaryOperator ::+    Ptr Value -> IO (Ptr BinaryOperator)++foreign import ccall unsafe "LLVM_Hs_HasNoSignedWrap" hasNoSignedWrap ::+    Ptr Value -> IO LLVMBool++foreign import ccall unsafe "LLVM_Hs_HasNoUnsignedWrap" hasNoUnsignedWrap ::+    Ptr Value -> IO LLVMBool++foreign import ccall unsafe "LLVM_Hs_IsExact" isExact ::+    Ptr Value -> IO LLVMBool++foreign import ccall unsafe "LLVM_Hs_GetFastMathFlags" getFastMathFlags ::+    Ptr Value -> IO FastMathFlags
+ src/LLVM/Internal/FFI/Bitcode.hs view
@@ -0,0 +1,26 @@+{-# LANGUAGE+  ForeignFunctionInterface+  #-}++-- | Functions to read and write LLVM bitcode+module LLVM.Internal.FFI.Bitcode where++import LLVM.Prelude++import LLVM.Internal.FFI.Context+import LLVM.Internal.FFI.LLVMCTypes+import LLVM.Internal.FFI.MemoryBuffer+import LLVM.Internal.FFI.Module+import LLVM.Internal.FFI.PtrHierarchy++import Foreign.C+import Foreign.Ptr++foreign import ccall unsafe "LLVM_Hs_ParseBitcode" parseBitcode ::+  Ptr Context -> Ptr MemoryBuffer -> Ptr (OwnerTransfered CString) -> IO (Ptr Module)++foreign import ccall unsafe "LLVM_Hs_WriteBitcode" writeBitcode ::+  Ptr Module -> Ptr RawOStream -> IO ()++                               +
+ src/LLVM/Internal/FFI/BitcodeC.cpp view
@@ -0,0 +1,34 @@+#define __STDC_LIMIT_MACROS+#include "llvm/IR/LLVMContext.h"+#include "llvm/IR/Module.h"+#include "llvm-c/Core.h"+#include "llvm/Support/raw_ostream.h"+#include "llvm/Support/MemoryBuffer.h"+#include "llvm/Bitcode/BitcodeReader.h"+#include "llvm/Bitcode/BitcodeWriter.h"++using namespace llvm;++extern "C" {++LLVMModuleRef LLVM_Hs_ParseBitcode(+	LLVMContextRef c,+	LLVMMemoryBufferRef mb, +	char **error+) {+    Expected<std::unique_ptr<Module>> moduleOrErr = parseBitcodeFile(unwrap(mb)->getMemBufferRef(), *unwrap(c));+    if (Error err = moduleOrErr.takeError()) {+        handleAllErrors(std::move(err), [&](ErrorInfoBase &eib) {+                *error = strdup(eib.message().c_str());+            });+        return nullptr;+    }+    return wrap(moduleOrErr.get().release());+}++void LLVM_Hs_WriteBitcode(LLVMModuleRef m, raw_ostream &os) {+	WriteBitcodeToFile(unwrap(m), os);+}++}+
+ src/LLVM/Internal/FFI/Builder.hs view
@@ -0,0 +1,184 @@+{-#+  LANGUAGE+  ForeignFunctionInterface,+  TemplateHaskell,+  ViewPatterns+  #-}+-- | FFI glue for llvm::IRBuilder - llvm's IR construction state object+module LLVM.Internal.FFI.Builder where++import LLVM.Prelude++import qualified Language.Haskell.TH as TH++import Foreign.Ptr+import Foreign.C++import qualified Data.List as List+import qualified Data.Map as Map++import qualified LLVM.AST.Instruction as A+import LLVM.Internal.InstructionDefs as ID++import LLVM.Internal.FFI.Cleanup+import LLVM.Internal.FFI.Context+import LLVM.Internal.FFI.LLVMCTypes+import LLVM.Internal.FFI.PtrHierarchy++data Builder++foreign import ccall unsafe "LLVMCreateBuilderInContext" createBuilderInContext ::+  Ptr Context -> IO (Ptr Builder)++foreign import ccall unsafe "LLVMDisposeBuilder" disposeBuilder ::+  Ptr Builder -> IO ()++foreign import ccall unsafe "LLVMPositionBuilderAtEnd" positionBuilderAtEnd ::+  Ptr Builder -> Ptr BasicBlock -> IO ()+++foreign import ccall unsafe "LLVMBuildRet" buildRet ::+  Ptr Builder -> Ptr Value -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVMBuildBr" buildBr ::+  Ptr Builder -> Ptr BasicBlock -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVMBuildCondBr" buildCondBr ::+  Ptr Builder -> Ptr Value -> Ptr BasicBlock -> Ptr BasicBlock -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVMBuildSwitch" buildSwitch ::+  Ptr Builder -> Ptr Value -> Ptr BasicBlock -> CUInt -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVMBuildIndirectBr" buildIndirectBr ::+  Ptr Builder -> Ptr Value -> CUInt -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVMBuildInvoke" buildInvoke ::+  Ptr Builder -> Ptr Value -> Ptr (Ptr Value) -> CUInt+              -> Ptr BasicBlock -> Ptr BasicBlock -> CString -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVMBuildResume" buildResume ::+  Ptr Builder -> Ptr Value -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVMBuildUnreachable" buildUnreachable ::+  Ptr Builder -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVM_Hs_BuildCleanupRet" buildCleanupRet ::+  Ptr Builder -> Ptr Value -> Ptr BasicBlock -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVM_Hs_BuildCatchRet" buildCatchRet ::+  Ptr Builder -> Ptr Value -> Ptr BasicBlock -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVM_Hs_BuildCatchSwitch" buildCatchSwitch ::+  Ptr Builder -> Ptr Value -> Ptr BasicBlock -> CUInt -> IO (Ptr Instruction)++$(do+  liftM concat $ sequence $ do+    let instrInfo = ID.outerJoin ID.astInstructionRecs ID.instructionDefs+    (lrn, ii) <- Map.toList instrInfo+    (TH.RecC _ (unzip3 -> (_, _, fieldTypes)), ID.InstructionDef { ID.cAPIName = a, ID.instructionKind = k }) <- case ii of+      (Just r, Just d) -> return (r,d)+      (Just _, Nothing) -> error $ "An AST instruction was not found in the LLVM instruction defs"+      (Nothing, Just ID.InstructionDef { ID.instructionKind = k }) | k /= ID.Terminator ->+        error $ "LLVM instruction def " ++ lrn ++ " not found in the AST"+      _ -> []++    let ats = map typeMapping (fieldTypes List.\\ [TH.ConT ''A.InstructionMetadata, TH.ConT ''A.FastMathFlags])+        cName = (if hasFlags fieldTypes then "LLVM_Hs_" else "LLVM") ++ "Build" ++ a+    rt <- case k of+            ID.Binary -> [[t| BinaryOperator |]]+            ID.Cast -> [[t| Instruction |]]+            _ -> []+    return $ foreignDecl cName ("build" ++ a) ([[t| Ptr Builder |]] ++ ats ++ [[t| CString |]]) [t| Ptr $(rt) |]+ )++foreign import ccall unsafe "LLVMBuildArrayAlloca" buildAlloca ::+  Ptr Builder -> Ptr Type -> Ptr Value -> CString -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVM_Hs_BuildLoad" buildLoad' ::+  Ptr Builder -> LLVMBool -> Ptr Value -> MemoryOrdering -> SynchronizationScope -> CUInt -> CString -> IO (Ptr Instruction)++buildLoad :: Ptr Builder -> LLVMBool -> Ptr Value -> (SynchronizationScope, MemoryOrdering) -> CUInt -> CString -> IO (Ptr Instruction)+buildLoad builder vol a' (ss, mo) al s = buildLoad' builder vol a' mo ss al s++foreign import ccall unsafe "LLVM_Hs_BuildStore" buildStore' ::+  Ptr Builder -> LLVMBool -> Ptr Value -> Ptr Value -> MemoryOrdering -> SynchronizationScope -> CUInt -> CString -> IO (Ptr Instruction)++buildStore :: Ptr Builder -> LLVMBool -> Ptr Value -> Ptr Value -> (SynchronizationScope, MemoryOrdering) -> CUInt -> CString -> IO (Ptr Instruction)+buildStore builder vol a' v' (ss, mo) al s = buildStore' builder vol a' v' mo ss al s++foreign import ccall unsafe "LLVMBuildGEP" buildGetElementPtr' ::+  Ptr Builder -> Ptr Value -> Ptr (Ptr Value) -> CUInt -> CString -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVMBuildInBoundsGEP" buildInBoundsGetElementPtr' ::+  Ptr Builder -> Ptr Value -> Ptr (Ptr Value) -> CUInt -> CString -> IO (Ptr Instruction)++buildGetElementPtr :: Ptr Builder -> LLVMBool -> Ptr Value -> (CUInt, Ptr (Ptr Value)) -> CString -> IO (Ptr Instruction)+buildGetElementPtr builder (LLVMBool 1) a (n, is) s = buildInBoundsGetElementPtr' builder a is n s+buildGetElementPtr builder (LLVMBool 0) a (n, is) s = buildGetElementPtr' builder a is n s++foreign import ccall unsafe "LLVM_Hs_BuildFence" buildFence' ::+  Ptr Builder -> MemoryOrdering -> SynchronizationScope -> CString -> IO (Ptr Instruction)++buildFence :: Ptr Builder -> (SynchronizationScope, MemoryOrdering) -> CString -> IO (Ptr Instruction)+buildFence builder (ss, mo) s = buildFence' builder mo ss s++foreign import ccall unsafe "LLVM_Hs_BuildAtomicCmpXchg" buildCmpXchg' ::+  Ptr Builder -> LLVMBool -> Ptr Value -> Ptr Value -> Ptr Value -> MemoryOrdering -> MemoryOrdering -> SynchronizationScope -> CString -> IO (Ptr Instruction)++buildCmpXchg :: Ptr Builder -> LLVMBool -> Ptr Value -> Ptr Value -> Ptr Value -> (SynchronizationScope, MemoryOrdering) -> MemoryOrdering -> CString -> IO (Ptr Instruction)+buildCmpXchg builder vol a e r (ss, smo) fmo s =  buildCmpXchg' builder vol a e r smo fmo ss s++foreign import ccall unsafe "LLVM_Hs_BuildAtomicRMW" buildAtomicRMW' ::+  Ptr Builder -> LLVMBool -> RMWOperation -> Ptr Value -> Ptr Value -> MemoryOrdering -> SynchronizationScope -> CString -> IO (Ptr Instruction)++buildAtomicRMW :: Ptr Builder -> LLVMBool -> RMWOperation -> Ptr Value -> Ptr Value -> (SynchronizationScope, MemoryOrdering) -> CString -> IO (Ptr Instruction)+buildAtomicRMW builder vol rmwOp a v (ss, mo) s = buildAtomicRMW' builder vol rmwOp a v mo ss s++foreign import ccall unsafe "LLVMBuildICmp" buildICmp ::+  Ptr Builder -> ICmpPredicate -> Ptr Value -> Ptr Value -> CString -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVMBuildFCmp" buildFCmp ::+  Ptr Builder -> FCmpPredicate -> Ptr Value -> Ptr Value -> CString -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVMBuildPhi" buildPhi ::+  Ptr Builder -> Ptr Type -> CString -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVMBuildCall" buildCall ::+  Ptr Builder -> Ptr Value -> Ptr (Ptr Value) -> CUInt -> CString -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVMBuildSelect" buildSelect ::+  Ptr Builder -> Ptr Value -> Ptr Value -> Ptr Value -> CString -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVMBuildVAArg" buildVAArg ::+  Ptr Builder -> Ptr Value -> Ptr Type -> CString -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVMBuildExtractElement" buildExtractElement ::+  Ptr Builder -> Ptr Value -> Ptr Value -> CString -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVMBuildInsertElement" buildInsertElement ::+  Ptr Builder -> Ptr Value -> Ptr Value -> Ptr Value -> CString -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVMBuildShuffleVector" buildShuffleVector ::+  Ptr Builder -> Ptr Value -> Ptr Value -> Ptr Constant -> CString -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVM_Hs_BuildExtractValue" buildExtractValue ::+  Ptr Builder -> Ptr Value -> Ptr CUInt -> CUInt -> CString -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVM_Hs_BuildInsertValue" buildInsertValue ::+  Ptr Builder -> Ptr Value -> Ptr Value -> Ptr CUInt -> CUInt -> CString -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVMBuildLandingPad" buildLandingPad' ::+  Ptr Builder -> Ptr Type -> Ptr Value -> CUInt -> CString -> IO (Ptr Instruction)++-- | The personality should be set via the function+buildLandingPad :: Ptr Builder -> Ptr Type -> CUInt -> CString -> IO (Ptr Instruction)+buildLandingPad builder ty numClauses name = buildLandingPad' builder ty nullPtr numClauses name++foreign import ccall unsafe "LLVM_Hs_BuildCleanupPad" buildCleanupPad ::+  Ptr Builder -> Ptr Value -> Ptr (Ptr Value) -> CUInt -> CString -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVM_Hs_BuildCatchPad" buildCatchPad ::+  Ptr Builder -> Ptr Value -> Ptr (Ptr Value) -> CUInt -> CString -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVM_Hs_SetFastMathFlags" setFastMathFlags ::+  Ptr Builder -> FastMathFlags -> IO ()
+ src/LLVM/Internal/FFI/BuilderC.cpp view
@@ -0,0 +1,223 @@+#define __STDC_LIMIT_MACROS+#include "llvm/IR/LLVMContext.h"+#include "llvm/IR/IRBuilder.h"++#include "llvm-c/Core.h"++#include "LLVM/Internal/FFI/Instruction.h"+#include "LLVM/Internal/FFI/BinaryOperator.h"++using namespace llvm;++namespace llvm {+static AtomicOrdering unwrap(LLVMAtomicOrdering l) {+	switch(l) {+#define ENUM_CASE(x) case LLVMAtomicOrdering ## x: return AtomicOrdering::x;+LLVM_HS_FOR_EACH_ATOMIC_ORDERING(ENUM_CASE)+#undef ENUM_CASE+	default: return AtomicOrdering(0);+	}+}++static SynchronizationScope unwrap(LLVMSynchronizationScope l) {+	switch(l) {+#define ENUM_CASE(x) case LLVM ## x ## SynchronizationScope: return x;+LLVM_HS_FOR_EACH_SYNCRONIZATION_SCOPE(ENUM_CASE)+#undef ENUM_CASE+	default: return SynchronizationScope(0);+	}+}+++static AtomicRMWInst::BinOp unwrap(LLVMAtomicRMWBinOp l) {+	switch(l) {+#define ENUM_CASE(x) case LLVMAtomicRMWBinOp ## x: return AtomicRMWInst::x;+LLVM_HS_FOR_EACH_RMW_OPERATION(ENUM_CASE)+#undef ENUM_CASE+	default: return AtomicRMWInst::BinOp(0);+	}+}++static FastMathFlags unwrap(LLVMFastMathFlags f) {+	FastMathFlags r = FastMathFlags();+#define ENUM_CASE(x,l) if (f & LLVM ## x) r.set ## x();+LLVM_HS_FOR_EACH_FAST_MATH_FLAG(ENUM_CASE)+#undef ENUM_CASE+	return r;+}++}++extern "C" {++#define ENUM_CASE(Op)																										\+LLVMValueRef LLVM_Hs_Build ## Op(																	\+	LLVMBuilderRef b,																											\+	LLVMBool nsw,																													\+	LLVMBool nuw,																													\+	LLVMValueRef o0,																											\+	LLVMValueRef o1,																											\+	const char *s																													\+) {																																			\+	return wrap(unwrap(b)->Create ## Op(unwrap(o0), unwrap(o1), s, nuw, nsw)); \+}+LLVM_HS_FOR_EACH_OVERFLOWING_BINARY_OPERATOR(ENUM_CASE)+#undef ENUM_CASE++#define ENUM_CASE(Op)																										\+LLVMValueRef LLVM_Hs_Build ## Op(																	\+	LLVMBuilderRef b,																											\+	LLVMBool exact,																												\+	LLVMValueRef o0,																											\+	LLVMValueRef o1,																											\+	const char *s																													\+) {																																			\+	return wrap(unwrap(b)->Create ## Op(unwrap(o0), unwrap(o1), s, exact)); \+}+LLVM_HS_FOR_EACH_POSSIBLY_EXACT_BINARY_OPERATOR(ENUM_CASE)+#undef ENUM_CASE++void LLVM_Hs_SetFastMathFlags(LLVMBuilderRef b, LLVMFastMathFlags f) {+	unwrap(b)->setFastMathFlags(unwrap(f));+}++LLVMValueRef LLVM_Hs_BuildLoad(+	LLVMBuilderRef b,+	LLVMBool isVolatile,+	LLVMValueRef p,+	LLVMAtomicOrdering atomicOrdering,+	LLVMSynchronizationScope synchScope,+	unsigned align,+	const char *name+) {+	LoadInst *i = unwrap(b)->CreateAlignedLoad(unwrap(p), align, isVolatile, name);+	i->setOrdering(unwrap(atomicOrdering));+	if (atomicOrdering != LLVMAtomicOrderingNotAtomic) i->setSynchScope(unwrap(synchScope));+	return wrap(i);+}++LLVMValueRef LLVM_Hs_BuildStore(+	LLVMBuilderRef b,+	LLVMBool isVolatile,+	LLVMValueRef p,+	LLVMValueRef v,+	LLVMAtomicOrdering atomicOrdering,+	LLVMSynchronizationScope synchScope,+	unsigned align,+	const char *name+) {+	StoreInst *i = unwrap(b)->CreateAlignedStore(unwrap(v), unwrap(p), align, isVolatile);+	i->setName(name);+	i->setOrdering(unwrap(atomicOrdering));+	if (atomicOrdering != LLVMAtomicOrderingNotAtomic) i->setSynchScope(unwrap(synchScope));+	return wrap(i);+}++LLVMValueRef LLVM_Hs_BuildFence(+	LLVMBuilderRef b, LLVMAtomicOrdering lao, LLVMSynchronizationScope lss, const char *name+) {+	FenceInst *i = unwrap(b)->CreateFence(unwrap(lao), unwrap(lss));+	i->setName(name);+	return wrap(i);+}++LLVMValueRef LLVM_Hs_BuildAtomicCmpXchg(+	LLVMBuilderRef b,+	LLVMBool v,+	LLVMValueRef ptr, +	LLVMValueRef cmp, +	LLVMValueRef n, +	LLVMAtomicOrdering successOrdering,+	LLVMAtomicOrdering failureOrdering,+	LLVMSynchronizationScope lss,+	const char *name+) {+	AtomicCmpXchgInst *a = unwrap(b)->CreateAtomicCmpXchg(+		unwrap(ptr), unwrap(cmp), unwrap(n), unwrap(successOrdering), unwrap(failureOrdering), unwrap(lss)+	);+	a->setVolatile(v);+	a->setName(name);+	return wrap(a);+}++LLVMValueRef LLVM_Hs_BuildAtomicRMW(+	LLVMBuilderRef b,+	LLVMBool v,+	LLVMAtomicRMWBinOp rmwOp,+	LLVMValueRef ptr, +	LLVMValueRef val, +	LLVMAtomicOrdering lao,+	LLVMSynchronizationScope lss,+	const char *name+) {+	AtomicRMWInst *a = unwrap(b)->CreateAtomicRMW(+		unwrap(rmwOp), unwrap(ptr), unwrap(val), unwrap(lao), unwrap(lss)+	);+	a->setVolatile(v);+	a->setName(name);+	return wrap(a);+}++LLVMValueRef LLVM_Hs_BuildExtractValue(+	LLVMBuilderRef b,+	LLVMValueRef a,+	unsigned *idxs,+	unsigned n,+	const char *name+) {+	return wrap(unwrap(b)->CreateExtractValue(unwrap(a), ArrayRef<unsigned>(idxs, n), name));+}++LLVMValueRef LLVM_Hs_BuildInsertValue(+	LLVMBuilderRef b,+	LLVMValueRef a,+	LLVMValueRef v,+	unsigned *idxs,+	unsigned n,+	const char *name+) {+	return wrap(unwrap(b)->CreateInsertValue(unwrap(a), unwrap(v), ArrayRef<unsigned>(idxs, n), name));+}++LLVMValueRef LLVM_Hs_BuildCleanupPad(LLVMBuilderRef b, LLVMValueRef parentPad,+                                     LLVMValueRef *args, unsigned numArgs,+                                     const char *name) {+  return wrap(unwrap(b)->CreateCleanupPad(unwrap(parentPad),+                                          makeArrayRef(unwrap(args), numArgs),+                                          name));+}++LLVMValueRef LLVM_Hs_BuildCatchPad(LLVMBuilderRef b, LLVMValueRef catchSwitch,+                                   LLVMValueRef *args, unsigned numArgs,+                                   const char *name) {+    return wrap(unwrap(b)->CreateCatchPad(unwrap(catchSwitch),+                                          makeArrayRef(unwrap(args), numArgs),+                                          name));+}++LLVMValueRef LLVM_Hs_BuildCleanupRet(LLVMBuilderRef b, LLVMValueRef cleanupPad,+                                     LLVMBasicBlockRef unwindDest) {+    // Due to the way name resolution works in llvm-hs, cleanupPad might not+    // actually be a CleanupPadInst. However, it will later be replaced by one.+    // Pretending that we have one is thus ok here.+    auto cleanupPad_ = static_cast<CleanupPadInst*>(unwrap<Value>(cleanupPad));+    return wrap(unwrap(b)->CreateCleanupRet(cleanupPad_,+                                            unwrap(unwindDest)));+}++LLVMValueRef LLVM_Hs_BuildCatchRet(LLVMBuilderRef b, LLVMValueRef catchPad,+                                   LLVMBasicBlockRef successor) {+    // Due to the way name resolution works in llvm-hs, catchPad might not+    // actually be a CatchPadInst. However, it will later be replaced by one.+    // Pretending that we have one is thus ok here.+    auto catchPad_ = static_cast<CatchPadInst *>(unwrap<Value>(catchPad));+    return wrap(unwrap(b)->CreateCatchRet(catchPad_, unwrap(successor)));+}++LLVMValueRef LLVM_Hs_BuildCatchSwitch(LLVMBuilderRef b, LLVMValueRef parentPad,+                                      LLVMBasicBlockRef unwindDest,+                                      unsigned numHandlers) {+    return wrap(unwrap(b)->CreateCatchSwitch(unwrap(parentPad),+                                             unwrap(unwindDest), numHandlers));+}+}
+ src/LLVM/Internal/FFI/ByteRangeCallback.hs view
@@ -0,0 +1,14 @@+{-# LANGUAGE+  ForeignFunctionInterface+  #-}+module LLVM.Internal.FFI.ByteRangeCallback where++import LLVM.Prelude++import Foreign.C+import Foreign.Ptr++type ByteRangeCallback = Ptr CChar -> CSize -> IO ()+foreign import ccall "wrapper" wrapByteRangeCallback :: +  ByteRangeCallback -> IO (FunPtr ByteRangeCallback)+
+ src/LLVM/Internal/FFI/CallingConvention.h view
@@ -0,0 +1,35 @@+#ifndef __LLVM_INTERNAL_FFI__CALLING_CONVENTION__H__+#define __LLVM_INTERNAL_FFI__CALLING_CONVENTION__H__++#define LLVM_HS_FOR_EACH_CALLING_CONVENTION(macro) \+  macro(C, 0)                                           \+  macro(Fast, 8)                                        \+  macro(Cold, 9)                                        \+  macro(GHC, 10)                                        \+  macro(HiPE, 11)                                       \+  macro(WebKit_JS, 12)                                  \+  macro(AnyReg, 13)                                     \+  macro(PreserveMost, 14)                               \+  macro(PreserveAll, 15)                                \+  macro(X86_StdCall, 64)                                \+  macro(X86_FastCall, 65)                               \+  macro(ARM_APCS, 66)                                   \+  macro(ARM_AAPCS, 67)                                  \+  macro(ARM_AAPCS_VFP, 68)                              \+  macro(MSP430_INTR, 69)                                \+  macro(X86_ThisCall, 70)                               \+  macro(PTX_Kernel, 71)                                 \+  macro(PTX_Device, 72)                                 \+  macro(SPIR_FUNC, 75)                                  \+  macro(SPIR_KERNEL, 76)                                \+  macro(Intel_OCL_BI, 77)                               \+  macro(X86_64_SysV, 78)                                \+  macro(X86_64_Win64, 79)++typedef enum {+#define ENUM_CASE(l,n) LLVM_Hs_CallingConvention_ ## l = n,+  LLVM_HS_FOR_EACH_CALLING_CONVENTION(ENUM_CASE)+#undef ENUM_CASE+} LLVM_Hs_CallingConvention;++#endif
+ src/LLVM/Internal/FFI/CallingConventionC.cpp view
@@ -0,0 +1,10 @@+#include "LLVM/Internal/FFI/CallingConvention.h"+#include "llvm/IR/CallingConv.h"++#define CHECK(l, n)                                                            \+    static_assert(unsigned(llvm::CallingConv::l) ==                            \+                      unsigned(LLVM_Hs_CallingConvention_##l),            \+                  "LLVM_Hs_CallingConvention enum out of sync w/ "        \+                  "llvm::CallingConv::ID for " #l);+LLVM_HS_FOR_EACH_CALLING_CONVENTION(CHECK)+#undef CHECK
+ src/LLVM/Internal/FFI/Cleanup.hs view
@@ -0,0 +1,83 @@+{-# LANGUAGE+  TemplateHaskell+  #-}+module LLVM.Internal.FFI.Cleanup where++import LLVM.Prelude++import Language.Haskell.TH+import Data.Sequence as Seq++import Foreign.C+import Foreign.Ptr++import LLVM.Internal.FFI.LLVMCTypes+import qualified LLVM.Internal.FFI.PtrHierarchy as FFI++import qualified LLVM.AST.IntegerPredicate as A (IntegerPredicate) +import qualified LLVM.AST.FloatingPointPredicate as A (FloatingPointPredicate) +import qualified LLVM.AST.Constant as A.C (Constant)+import qualified LLVM.AST.Operand as A (Operand)+import qualified LLVM.AST.Type as A (Type)+import qualified LLVM.AST.Instruction as A (FastMathFlags)++foreignDecl :: String -> String -> [TypeQ] -> TypeQ -> DecsQ+foreignDecl cName hName argTypeQs returnTypeQ = do+  let foreignDecl' hName argTypeQs = +        forImpD cCall unsafe cName (mkName hName) +                  (foldr (\a b -> appT (appT arrowT a) b) (appT (conT ''IO) returnTypeQ) argTypeQs)+      splitTuples :: [Type] -> Q ([Type], [Pat], [Exp])+      splitTuples ts = do+        let f :: Type -> Q (Seq Type, Pat, Seq Exp)+            f x@(AppT _ _) = maybe (d x) (\q -> q >>= \(ts, ps, es) -> return (ts, TupP (toList ps), es)) (g 0 x)+            f x = d x+            g :: Int -> Type -> Maybe (Q (Seq Type, Seq Pat, Seq Exp))+            g n (TupleT m) | m == n = return (return (Seq.empty, Seq.empty, Seq.empty))+            g n (AppT a b) = do+              k <- g (n+1) a+              return $ do+                (ts, ps, es) <- k+                (ts', p', es') <- f b+                return (ts >< ts', ps |> p', es >< es')+            g _ _ = Nothing+            d :: Type -> Q (Seq Type, Pat, Seq Exp)+            d x = do+              n <- newName "v"+              return (Seq.singleton x, VarP n, Seq.singleton (VarE n))+            seqsToList :: [Seq a] -> [a]+            seqsToList = toList . foldr (><) Seq.empty+                +        (tss, ps, ess) <- liftM unzip3 . mapM f $ ts+        return (seqsToList tss, ps, seqsToList ess)++                                +  argTypes <- sequence argTypeQs+  (ts, ps, es) <- splitTuples argTypes+  let phName = hName ++ "'"+  sequence [+    foreignDecl' phName (map return ts),+    funD (mkName hName) [+     clause (map return ps) (normalB (foldl appE (varE (mkName phName)) (map return es))) []+    ]+   ]++-- | The LLVM C-API for instructions with boolean flags (e.g. nsw) and is weak, so they get+-- separated out for different handling. This check is an accurate but crude test for whether+-- an instruction needs such handling.+hasFlags :: [Type] -> Bool+hasFlags = any (== ConT ''Bool)++typeMapping :: Type -> TypeQ+typeMapping t = case t of+  ConT h | h == ''Bool -> [t| LLVMBool |]+         | h == ''Int32 -> [t| CInt |]+         | h == ''Word32 -> [t| CUInt |]+         | h == ''String -> [t| CString |]+         | h == ''A.Operand -> [t| Ptr FFI.Value |]+         | h == ''A.Type -> [t| Ptr FFI.Type |]+         | h == ''A.C.Constant -> [t| Ptr FFI.Constant |]+         | h == ''A.FloatingPointPredicate -> [t| FCmpPredicate |]+         | h == ''A.IntegerPredicate -> [t| ICmpPredicate |]+         | h == ''A.FastMathFlags -> [t| FastMathFlags |]+  AppT ListT x -> foldl1 appT [tupleT 2, [t| CUInt |], appT [t| Ptr |] (typeMapping x)]+  x -> error $ "type not handled in Cleanup typeMapping: " ++ show x
+ src/LLVM/Internal/FFI/CommandLine.hs view
@@ -0,0 +1,15 @@+{-# LANGUAGE+  ForeignFunctionInterface+  #-}+module LLVM.Internal.FFI.CommandLine where++import LLVM.Prelude++import Foreign.Ptr+import Foreign.C++foreign import ccall unsafe "LLVM_Hs_ParseCommandLineOptions" parseCommandLineOptions' ::+  CUInt -> Ptr (Ptr CChar) -> Ptr CChar -> IO ()++parseCommandLineOptions :: (CUInt, Ptr (Ptr CChar)) -> Ptr CChar -> IO ()+parseCommandLineOptions = uncurry parseCommandLineOptions'
+ src/LLVM/Internal/FFI/CommandLineC.cpp view
@@ -0,0 +1,12 @@+#define __STDC_LIMIT_MACROS+#include "llvm/Support/CommandLine.h"++using namespace llvm;++extern "C" {++void LLVM_Hs_ParseCommandLineOptions(unsigned argc, const char * const *argv, const char *overview) {+	cl::ParseCommandLineOptions(argc, argv, overview);+}++}
+ src/LLVM/Internal/FFI/Constant.h view
@@ -0,0 +1,20 @@+#ifndef __LLVM_INTERNAL_FFI__CONSTANT__H__+#define __LLVM_INTERNAL_FFI__CONSTANT__H__++#define LLVM_HS_FOR_EACH_FLOAT_SEMANTICS(macro) \+	macro(IEEEhalf) \+	macro(IEEEsingle) \+	macro(IEEEdouble) \+	macro(IEEEquad) \+	macro(PPCDoubleDouble) \+	macro(x87DoubleExtended) \+	macro(Bogus)++typedef enum {+#define ENUM_CASE(x) LLVMFloatSemantics ## x,+LLVM_HS_FOR_EACH_FLOAT_SEMANTICS(ENUM_CASE)+#undef ENUM_CASE+} LLVMFloatSemantics;+++#endif
+ src/LLVM/Internal/FFI/Constant.hs view
@@ -0,0 +1,145 @@+{-# LANGUAGE+  TemplateHaskell,+  ForeignFunctionInterface,+  MultiParamTypeClasses,+  UndecidableInstances,+  ViewPatterns+  #-}+-- | FFI functions for handling the LLVM Constant class+module LLVM.Internal.FFI.Constant where++import LLVM.Prelude++import qualified Language.Haskell.TH as TH+import qualified LLVM.Internal.InstructionDefs as ID++import qualified Data.Map as Map++import Foreign.Ptr+import Foreign.C++import LLVM.Internal.FFI.PtrHierarchy+import LLVM.Internal.FFI.Context+import LLVM.Internal.FFI.Cleanup+import LLVM.Internal.FFI.LLVMCTypes++foreign import ccall unsafe "LLVMIsConstant" isConstant ::+  Ptr Value -> IO (CUInt)++foreign import ccall unsafe "LLVMIsAConstant" isAConstant ::+  Ptr Value -> IO (Ptr Constant)++foreign import ccall unsafe "LLVMIsAConstantInt" isAConstantInt ::+  Ptr Value -> IO (Ptr Constant)++foreign import ccall unsafe "LLVMGetOperand" getConstantOperand ::+  Ptr Constant -> CUInt -> IO (Ptr Constant)++foreign import ccall unsafe "LLVMIsAConstantPointerNull" isAConstantPointerNull ::+  Ptr Value -> IO (Ptr Constant)++foreign import ccall unsafe "LLVM_Hs_GetConstantIntWords" getConstantIntWords ::+  Ptr Constant -> Ptr CUInt -> IO (Ptr Word64)++foreign import ccall unsafe "LLVM_Hs_ConstFloatDoubleValue" constFloatDoubleValue ::+  Ptr Constant -> IO CDouble++foreign import ccall unsafe "LLVM_Hs_ConstFloatFloatValue" constFloatFloatValue ::+  Ptr Constant -> IO CFloat++foreign import ccall unsafe "LLVMConstStructInContext" constStructInContext' ::+  Ptr Context -> Ptr (Ptr Constant) -> CUInt -> LLVMBool -> IO (Ptr Constant)++constStructInContext :: Ptr Context -> (CUInt, Ptr (Ptr Constant)) -> LLVMBool -> IO (Ptr Constant)+constStructInContext ctx (n, cs) p = constStructInContext' ctx cs n p++foreign import ccall unsafe "LLVMConstNamedStruct" constNamedStruct' ::+  Ptr Type -> Ptr (Ptr Constant) -> CUInt -> IO (Ptr Constant)++constNamedStruct :: Ptr Type -> (CUInt, Ptr (Ptr Constant)) -> IO (Ptr Constant)+constNamedStruct ty (n, cs) = constNamedStruct' ty cs n++foreign import ccall unsafe "LLVM_Hs_GetConstantDataSequentialElementAsConstant" getConstantDataSequentialElementAsConstant ::+  Ptr Constant -> CUInt -> IO (Ptr Constant)++foreign import ccall unsafe "LLVMConstIntOfArbitraryPrecision" constantIntOfArbitraryPrecision' ::+  Ptr Type -> CUInt -> Ptr Word64 -> IO (Ptr Constant)++constantIntOfArbitraryPrecision :: Ptr Type -> (CUInt, Ptr Word64) -> IO (Ptr Constant)+constantIntOfArbitraryPrecision t = uncurry (constantIntOfArbitraryPrecision' t)++foreign import ccall unsafe "LLVM_Hs_ConstFloatOfArbitraryPrecision" constantFloatOfArbitraryPrecision ::+  Ptr Context -> CUInt -> Ptr Word64 -> FloatSemantics -> IO (Ptr Constant)++foreign import ccall unsafe "LLVM_Hs_GetConstantFloatWords" getConstantFloatWords ::+  Ptr Constant -> Ptr Word64 -> IO ()++foreign import ccall unsafe "LLVMConstVector" constantVector' ::+  Ptr (Ptr Constant) -> CUInt -> IO (Ptr Constant)++constantVector :: (CUInt, Ptr (Ptr Constant)) -> IO (Ptr Constant)+constantVector (n, cs) = constantVector' cs n++foreign import ccall unsafe "LLVMConstNull" constantNull ::+  Ptr Type -> IO (Ptr Constant)++foreign import ccall unsafe "LLVMConstArray" constantArray' ::+  Ptr Type -> Ptr (Ptr Constant) -> CUInt -> IO (Ptr Constant)++constantArray :: Ptr Type -> (CUInt, Ptr (Ptr Constant)) -> IO (Ptr Constant)+constantArray t (n, cs) = constantArray' t cs n++foreign import ccall unsafe "LLVM_Hs_ConstCast" constantCast ::+  CPPOpcode -> Ptr Constant -> Ptr Type -> IO (Ptr Constant)++foreign import ccall unsafe "LLVM_Hs_ConstBinaryOperator" constantBinaryOperator ::+  CPPOpcode -> Ptr Constant -> Ptr Constant -> IO (Ptr Constant)++$(do+   let constExprInfo = ID.innerJoin (ID.innerJoin ID.astConstantRecs ID.astInstructionRecs) ID.instructionDefs+   liftM concat $ sequence $ do+     (name, ((TH.RecC _ (unzip3 -> (_, _, fieldTypes)),_), ID.InstructionDef { ID.instructionKind = ik })) <- Map.toList constExprInfo+     prefix <- case ik of+                 ID.Other -> return "LLVM"+                 ID.Binary | hasFlags fieldTypes -> return "LLVM_Hs_"+                 _ -> []+     return $+       foreignDecl (prefix ++ "Const" ++ name) ("constant" ++ name) (map typeMapping fieldTypes) [t| Ptr Constant |]+  )++foreign import ccall unsafe "LLVMConstGEP" constantGetElementPtr' ::+  Ptr Constant -> Ptr (Ptr Constant) -> CUInt -> IO (Ptr Constant)++foreign import ccall unsafe "LLVMConstInBoundsGEP" constantInBoundsGetElementPtr' ::+  Ptr Constant -> Ptr (Ptr Constant) -> CUInt -> IO (Ptr Constant)++constantGetElementPtr :: LLVMBool -> Ptr Constant -> (CUInt, Ptr (Ptr Constant)) -> IO (Ptr Constant)+constantGetElementPtr (LLVMBool ib) a (n, is) =+  (case ib of { 0 -> constantGetElementPtr'; 1 -> constantInBoundsGetElementPtr' }) a is n++foreign import ccall unsafe "LLVM_Hs_GetConstCPPOpcode" getConstantCPPOpcode ::+  Ptr Constant -> IO CPPOpcode++foreign import ccall unsafe "LLVM_Hs_GetConstPredicate" getConstantICmpPredicate ::+  Ptr Constant -> IO ICmpPredicate++foreign import ccall unsafe "LLVM_Hs_GetConstPredicate" getConstantFCmpPredicate ::+  Ptr Constant -> IO FCmpPredicate++foreign import ccall unsafe "LLVM_Hs_GetConstIndices" getConstantIndices ::+  Ptr Constant -> Ptr CUInt -> IO (Ptr CUInt)++foreign import ccall unsafe "LLVMGetUndef" constantUndef ::+  Ptr Type -> IO (Ptr Constant)++foreign import ccall unsafe "LLVMBlockAddress" blockAddress ::+  Ptr Value -> Ptr BasicBlock -> IO (Ptr Constant)++foreign import ccall unsafe "LLVM_Hs_GetBlockAddressFunction" getBlockAddressFunction ::+  Ptr Constant -> IO (Ptr Value)++foreign import ccall unsafe "LLVM_Hs_GetBlockAddressBlock" getBlockAddressBlock ::+  Ptr Constant -> IO (Ptr BasicBlock)++foreign import ccall unsafe "LLVM_Hs_GetConstTokenNone" getConstTokenNone ::+  Ptr Context -> IO (Ptr Constant)
+ src/LLVM/Internal/FFI/ConstantC.cpp view
@@ -0,0 +1,114 @@+#define __STDC_LIMIT_MACROS+#include "llvm/IR/LLVMContext.h"+#include "llvm/IR/Constants.h"+#include "llvm/IR/Function.h"++#include "llvm-c/Core.h"+#include "LLVM/Internal/FFI/Value.h"+#include "LLVM/Internal/FFI/Constant.h"+#include "LLVM/Internal/FFI/BinaryOperator.h"++using namespace llvm;++namespace llvm {++static const struct fltSemantics &unwrap(LLVMFloatSemantics s) {+	switch(s) {+#define ENUM_CASE(x) case LLVMFloatSemantics ## x: return APFloat::x();+LLVM_HS_FOR_EACH_FLOAT_SEMANTICS(ENUM_CASE)+#undef ENUM_CASE+    default: return APFloat::Bogus();+	}+}++}++extern "C" {++LLVMValueRef LLVM_Hs_GetConstantDataSequentialElementAsConstant(LLVMValueRef v, unsigned i) {+	return wrap(unwrap<ConstantDataSequential>(v)->getElementAsConstant(i));+}++LLVMValueRef LLVM_Hs_GetBlockAddressFunction(LLVMValueRef v) {+	return wrap(unwrap<BlockAddress>(v)->getFunction());+}++LLVMBasicBlockRef LLVM_Hs_GetBlockAddressBlock(LLVMValueRef v) {+	return wrap(unwrap<BlockAddress>(v)->getBasicBlock());+}++double LLVM_Hs_ConstFloatDoubleValue(LLVMValueRef v) {+	return unwrap<ConstantFP>(v)->getValueAPF().convertToDouble();+}++float LLVM_Hs_ConstFloatFloatValue(LLVMValueRef v) {+	return unwrap<ConstantFP>(v)->getValueAPF().convertToFloat();+}++LLVMValueRef LLVM_Hs_ConstCast(unsigned opcode, LLVMValueRef v, LLVMTypeRef t) {+	return wrap(ConstantExpr::getCast(opcode, unwrap<Constant>(v), unwrap(t)));+}++LLVMValueRef LLVM_Hs_ConstBinaryOperator(unsigned opcode, LLVMValueRef o0, LLVMValueRef o1) {+	return wrap(ConstantExpr::get(opcode, unwrap<Constant>(o0), unwrap<Constant>(o1)));+}++#define CASE_CODE(op)																										\+LLVMValueRef LLVM_Hs_Const ## op(unsigned nsw, unsigned nuw, LLVMValueRef o0, LLVMValueRef o1) { \+	return wrap(ConstantExpr::get ## op(unwrap<Constant>(o0), unwrap<Constant>(o1), nuw != 0, nsw != 0)); \+}+LLVM_HS_FOR_EACH_OVERFLOWING_BINARY_OPERATOR(CASE_CODE)+#undef CASE_CODE++#define CASE_CODE(op)																										\+LLVMValueRef LLVM_Hs_Const ## op(unsigned isExact, LLVMValueRef o0, LLVMValueRef o1) {	\+	return wrap(ConstantExpr::get ## op(unwrap<Constant>(o0), unwrap<Constant>(o1), isExact != 0));	\+}+LLVM_HS_FOR_EACH_POSSIBLY_EXACT_BINARY_OPERATOR(CASE_CODE)+#undef CASE_CODE++unsigned LLVM_Hs_GetConstCPPOpcode(LLVMValueRef v) {+	return unwrap<ConstantExpr>(v)->getOpcode();+}++unsigned LLVM_Hs_GetConstPredicate(LLVMValueRef v) {+	return unwrap<ConstantExpr>(v)->getPredicate();+}++const unsigned *LLVM_Hs_GetConstIndices(LLVMValueRef v, unsigned *n) {+	ArrayRef<unsigned> r = unwrap<ConstantExpr>(v)->getIndices();+	*n = r.size();+	return r.data();+}++const uint64_t *LLVM_Hs_GetConstantIntWords(LLVMValueRef v, unsigned *n) {+	const APInt &i = unwrap<ConstantInt>(v)->getValue();+	*n = i.getNumWords();+	return i.getRawData();+}++LLVMValueRef LLVM_Hs_ConstFloatOfArbitraryPrecision(+	LLVMContextRef c,+	unsigned bits,+	const uint64_t *words,+	LLVMFloatSemantics semantics+) {+	return wrap(+		ConstantFP::get(+			*unwrap(c),+			APFloat(unwrap(semantics), APInt(bits, ArrayRef<uint64_t>(words, (bits-1)/64 + 1)))+		)+	);+}++void LLVM_Hs_GetConstantFloatWords(LLVMValueRef v, uint64_t *bits) {+	APInt a = unwrap<ConstantFP>(v)->getValueAPF().bitcastToAPInt();+	for(unsigned i=0; i != a.getNumWords(); ++i) bits[i] = a.getRawData()[i];+}++LLVMValueRef LLVM_Hs_GetConstTokenNone(LLVMContextRef context) {+	return wrap(ConstantTokenNone::get(*unwrap(context)));+}+++}
+ src/LLVM/Internal/FFI/Context.hs view
@@ -0,0 +1,28 @@+{-# LANGUAGE+  ForeignFunctionInterface+  #-}++-- | Functions for handling the LLVMContext class. In all other LLVM interfaces,+-- | prefer the newer explicitly thread-aware variants which use contexts+-- | over corresponding older variants which implicitly reference a global context.+-- | This choice allows multiple threads to do independent work with LLVM safely.+module LLVM.Internal.FFI.Context where++import LLVM.Prelude++import Foreign.Ptr++-- | a blind type to correspond to LLVMContext+data Context++-- | <http://llvm.org/doxygen/group__LLVMCCoreContext.html#gaac4f39a2d0b9735e64ac7681ab543b4c>+foreign import ccall unsafe "LLVMContextCreate" contextCreate ::+    IO (Ptr Context)++-- | <http://llvm.org/doxygen/group__LLVMCCoreContext.html#ga0055cde9a9b2497b332d639d8844a810>+foreign import ccall unsafe "LLVMGetGlobalContext" getGlobalContext ::+    IO (Ptr Context)++-- | <http://llvm.org/doxygen/group__LLVMCCoreContext.html#ga9cf8b0fb4a546d4cdb6f64b8055f5f57>+foreign import ccall unsafe "LLVMContextDispose" contextDispose ::+    Ptr Context -> IO ()
+ src/LLVM/Internal/FFI/DataLayout.hs view
@@ -0,0 +1,26 @@+{-# LANGUAGE+  ForeignFunctionInterface+  #-}++module LLVM.Internal.FFI.DataLayout where++import LLVM.Prelude++import Foreign.C.String+import Foreign.Ptr++import LLVM.Internal.FFI.LLVMCTypes++data DataLayout++-- Oooh those wacky LLVM C-API coders: C API called DataLayout TargetData.+-- Great. Just great.++foreign import ccall unsafe "LLVMCreateTargetData" createDataLayout :: +  CString -> IO (Ptr DataLayout)++foreign import ccall unsafe "LLVMDisposeTargetData" disposeDataLayout :: +  Ptr DataLayout -> IO ()++foreign import ccall unsafe "LLVMCopyStringRepOfTargetData" dataLayoutToString ::+  Ptr DataLayout -> IO (OwnerTransfered CString)
+ src/LLVM/Internal/FFI/ExecutionEngine.hs view
@@ -0,0 +1,71 @@+{-# LANGUAGE+  ForeignFunctionInterface+  #-}++module LLVM.Internal.FFI.ExecutionEngine where++import LLVM.Prelude++import Foreign.Ptr+import Foreign.C++import LLVM.Internal.FFI.PtrHierarchy+import LLVM.Internal.FFI.Module+import LLVM.Internal.FFI.LLVMCTypes++data ExecutionEngine++foreign import ccall unsafe "LLVMCreateExecutionEngineForModule" createExecutionEngineForModule ::+  Ptr (Ptr ExecutionEngine) -> Ptr Module -> Ptr (OwnerTransfered CString) -> IO CUInt++foreign import ccall unsafe "LLVMCreateInterpreterForModule" createInterpreterForModule ::+  Ptr (Ptr ExecutionEngine) -> Ptr Module -> Ptr (OwnerTransfered CString) -> IO CUInt++foreign import ccall unsafe "LLVMCreateJITCompilerForModule" createJITCompilerForModule ::+  Ptr (Ptr ExecutionEngine) -> Ptr Module -> CUInt -> Ptr (OwnerTransfered CString) -> IO CUInt++foreign import ccall unsafe "LLVMCreateMCJITCompilerForModule" createMCJITCompilerForModule ::+  Ptr (Ptr ExecutionEngine) -> Ptr Module -> Ptr MCJITCompilerOptions -> CSize -> Ptr (OwnerTransfered CString) -> IO CUInt++foreign import ccall unsafe "LLVMDisposeExecutionEngine" disposeExecutionEngine ::+  Ptr ExecutionEngine -> IO ()++foreign import ccall unsafe "LLVMAddModule" addModule ::+  Ptr ExecutionEngine -> Ptr Module -> IO ()++foreign import ccall unsafe "LLVMRemoveModule" removeModule ::+  Ptr ExecutionEngine -> Ptr Module -> Ptr (Ptr Module) -> Ptr CString -> IO CUInt++foreign import ccall unsafe "LLVMFindFunction" findFunction ::+  Ptr ExecutionEngine -> CString -> Ptr (Ptr Function) -> IO CUInt++foreign import ccall unsafe "LLVMGetPointerToGlobal" getPointerToGlobal ::+  Ptr ExecutionEngine -> Ptr GlobalValue -> IO (Ptr ())++foreign import ccall unsafe "LLVMLinkInInterpreter" linkInInterpreter :: +  IO ()++foreign import ccall unsafe "LLVMLinkInMCJIT" linkInMCJIT :: +  IO ()++data MCJITCompilerOptions++foreign import ccall unsafe "LLVM_Hs_GetMCJITCompilerOptionsSize" getMCJITCompilerOptionsSize ::+  IO CSize++foreign import ccall unsafe "LLVMInitializeMCJITCompilerOptions" initializeMCJITCompilerOptions ::+  Ptr MCJITCompilerOptions -> CSize -> IO ()++foreign import ccall unsafe "LLVM_Hs_SetMCJITCompilerOptionsOptLevel" setMCJITCompilerOptionsOptLevel ::+  Ptr MCJITCompilerOptions -> CUInt -> IO ()++foreign import ccall unsafe "LLVM_Hs_SetMCJITCompilerOptionsCodeModel" setMCJITCompilerOptionsCodeModel ::+  Ptr MCJITCompilerOptions -> CodeModel -> IO ()++foreign import ccall unsafe "LLVM_Hs_SetMCJITCompilerOptionsNoFramePointerElim" setMCJITCompilerOptionsNoFramePointerElim ::+  Ptr MCJITCompilerOptions -> LLVMBool -> IO ()++foreign import ccall unsafe "LLVM_Hs_SetMCJITCompilerOptionsEnableFastISel" setMCJITCompilerOptionsEnableFastISel ::+  Ptr MCJITCompilerOptions -> LLVMBool -> IO ()++
+ src/LLVM/Internal/FFI/ExecutionEngineC.cpp view
@@ -0,0 +1,30 @@+#define __STDC_LIMIT_MACROS+#include "llvm/IR/LLVMContext.h"+#include "llvm-c/ExecutionEngine.h"++using namespace llvm;++extern "C" {++size_t LLVM_Hs_GetMCJITCompilerOptionsSize() {+  return sizeof(struct LLVMMCJITCompilerOptions);+}++void LLVM_Hs_SetMCJITCompilerOptionsOptLevel(struct LLVMMCJITCompilerOptions *o, unsigned x) {+  o->OptLevel = x;+}++void LLVM_Hs_SetMCJITCompilerOptionsCodeModel(struct LLVMMCJITCompilerOptions *o, LLVMCodeModel x) {+  o->CodeModel = x;+}++void LLVM_Hs_SetMCJITCompilerOptionsNoFramePointerElim(struct LLVMMCJITCompilerOptions *o, LLVMBool x) {+  o->NoFramePointerElim = x;+}++void LLVM_Hs_SetMCJITCompilerOptionsEnableFastISel(struct LLVMMCJITCompilerOptions *o, LLVMBool x) {+  o->EnableFastISel = x;+}++}+
+ src/LLVM/Internal/FFI/Function.hs view
@@ -0,0 +1,72 @@+{-# LANGUAGE+  ForeignFunctionInterface,+  MultiParamTypeClasses+  #-}++module LLVM.Internal.FFI.Function where++import LLVM.Prelude++import Foreign.Ptr+import Foreign.C++import LLVM.Internal.FFI.Attribute+import LLVM.Internal.FFI.Context+import LLVM.Internal.FFI.LLVMCTypes+import LLVM.Internal.FFI.PtrHierarchy++foreign import ccall unsafe "LLVMGetFunctionCallConv" getFunctionCallingConvention ::+  Ptr Function -> IO CallingConvention++foreign import ccall unsafe "LLVMSetFunctionCallConv" setFunctionCallingConvention ::+  Ptr Function -> CallingConvention -> IO ()++foreign import ccall unsafe "LLVM_Hs_GetFunctionMixedAttributeSet" getMixedAttributeSet ::+  Ptr Function -> IO MixedAttributeSet++foreign import ccall unsafe "LLVM_Hs_SetFunctionMixedAttributeSet" setMixedAttributeSet ::+  Ptr Function -> MixedAttributeSet -> IO ()++foreign import ccall unsafe "LLVMGetFirstBasicBlock" getFirstBasicBlock ::+  Ptr Function -> IO (Ptr BasicBlock)++foreign import ccall unsafe "LLVMGetLastBasicBlock" getLastBasicBlock ::+  Ptr Function -> IO (Ptr BasicBlock)++foreign import ccall unsafe "LLVMGetNextBasicBlock" getNextBasicBlock ::+  Ptr BasicBlock -> IO (Ptr BasicBlock)++foreign import ccall unsafe "LLVMAppendBasicBlockInContext" appendBasicBlockInContext ::+  Ptr Context -> Ptr Function -> CString -> IO (Ptr BasicBlock)+++foreign import ccall unsafe "LLVMCountParams" countParams ::+  Ptr Function -> IO CUInt++foreign import ccall unsafe "LLVMGetParams" getParams ::+  Ptr Function -> Ptr (Ptr Parameter) -> IO ()++foreign import ccall unsafe "LLVMGetGC" getGC ::+  Ptr Function -> IO CString++foreign import ccall unsafe "LLVMSetGC" setGC ::+  Ptr Function -> CString -> IO ()+++foreign import ccall unsafe "LLVM_Hs_HasFunctionPrefixData" hasPrefixData ::+  Ptr Function -> IO LLVMBool++foreign import ccall unsafe "LLVM_Hs_GetFunctionPrefixData" getPrefixData ::+  Ptr Function -> IO (Ptr Constant)++foreign import ccall unsafe "LLVM_Hs_SetFunctionPrefixData" setPrefixData ::+  Ptr Function -> Ptr Constant -> IO ()++foreign import ccall unsafe "LLVMHasPersonalityFn" hasPersonalityFn ::+  Ptr Function -> IO LLVMBool++foreign import ccall unsafe "LLVM_Hs_SetPersonalityFn" setPersonalityFn ::+  Ptr Function -> Ptr Constant -> IO ()++foreign import ccall unsafe "LLVMGetPersonalityFn" getPersonalityFn ::+  Ptr Function -> IO (Ptr Constant)
+ src/LLVM/Internal/FFI/FunctionC.cpp view
@@ -0,0 +1,41 @@+#define __STDC_LIMIT_MACROS+#include "llvm/IR/LLVMContext.h"+#include "llvm/IR/Attributes.h"+#include "llvm/IR/Function.h"+#include "llvm/IR/Value.h"++#include "llvm-c/Core.h"+#include "LLVM/Internal/FFI/AttributeC.hpp"++using namespace llvm;++extern "C" {++const AttributeSetImpl *LLVM_Hs_GetFunctionMixedAttributeSet(LLVMValueRef f) {+	return wrap(unwrap<Function>(f)->getAttributes());+}++void LLVM_Hs_SetFunctionMixedAttributeSet(LLVMValueRef f, AttributeSetImpl *asi) {+	unwrap<Function>(f)->setAttributes(unwrap(asi));+}++LLVMBool LLVM_Hs_HasFunctionPrefixData(LLVMValueRef f) {+  return unwrap<Function>(f)->hasPrefixData();+}++LLVMValueRef LLVM_Hs_GetFunctionPrefixData(LLVMValueRef f) {+  return wrap(unwrap<Function>(f)->getPrefixData());+}++void LLVM_Hs_SetFunctionPrefixData(LLVMValueRef f, LLVMValueRef p) {+  unwrap<Function>(f)->setPrefixData(unwrap<Constant>(p));+}++// This wrapper is necessary because LLVMSetPersonalityFn fails if+// personalityFn is a nullptr even though the C++ API allows that.+void LLVM_Hs_SetPersonalityFn(LLVMValueRef fn, LLVMValueRef personalityFn) {+    unwrap<Function>(fn)->setPersonalityFn(personalityFn == nullptr ?+                                           nullptr : unwrap<Constant>(personalityFn));+}++}
+ src/LLVM/Internal/FFI/GlobalAlias.hs view
@@ -0,0 +1,26 @@+{-# LANGUAGE+  ForeignFunctionInterface,+  MultiParamTypeClasses,+  UndecidableInstances+  #-}+-- | FFI functions for handling the LLVM GlobalAlias class+module LLVM.Internal.FFI.GlobalAlias where++import LLVM.Prelude++import Foreign.Ptr++import LLVM.Internal.FFI.PtrHierarchy++-- | test if a 'Value' is a 'GlobalAlias'+foreign import ccall unsafe "LLVMIsAGlobalAlias" isAGlobalAlias ::+    Ptr Value -> IO (Ptr GlobalAlias)++-- | get the constant aliased by this alias+foreign import ccall unsafe "LLVM_Hs_GetAliasee" getAliasee ::+    Ptr GlobalAlias -> IO (Ptr Constant)++-- | set the constant aliased by this alias+foreign import ccall unsafe "LLVM_Hs_SetAliasee" setAliasee ::+    Ptr GlobalAlias -> Ptr Constant -> IO ()+
+ src/LLVM/Internal/FFI/GlobalAliasC.cpp view
@@ -0,0 +1,22 @@+#define __STDC_LIMIT_MACROS+#include "llvm/IR/LLVMContext.h"+#include "llvm/IR/GlobalAlias.h"+#include "llvm/IR/GlobalObject.h"++#include "llvm-c/Core.h"++#include <iostream>++using namespace llvm;++extern "C" {++LLVMValueRef LLVM_Hs_GetAliasee(LLVMValueRef g) {+	return wrap(unwrap<GlobalAlias>(g)->getAliasee());+}++void LLVM_Hs_SetAliasee(LLVMValueRef g, LLVMValueRef c) {+	unwrap<GlobalAlias>(g)->setAliasee(unwrap<Constant>(c));+}++}
+ src/LLVM/Internal/FFI/GlobalValue.h view
@@ -0,0 +1,58 @@+#ifndef __LLVM_INTERNAL_FFI__GLOBAL_VALUE__H__+#define __LLVM_INTERNAL_FFI__GLOBAL_VALUE__H__++#define LLVM_HS_FOR_EACH_LINKAGE(macro)		\+	macro(External)																\+	macro(AvailableExternally)										\+	macro(LinkOnceAny)														\+	macro(LinkOnceODR)														\+	macro(WeakAny)																\+	macro(WeakODR)																\+	macro(Appending)															\+	macro(Internal)																\+	macro(Private)																\+	macro(ExternalWeak)														\+	macro(Common)++#define LLVM_HS_FOR_EACH_VISIBILITY(macro)	\+	macro(Default)																\+	macro(Hidden)																	\+	macro(Protected)															\++#define LLVM_HS_FOR_EACH_COMDAT_SELECTION_KIND(macro)	\+	macro(Any)                                                \+	macro(ExactMatch)                                         \+	macro(Largest)                                            \+	macro(NoDuplicates)                                       \+	macro(SameSize)++typedef enum {+#define ENUM_CASE(n) LLVM_Hs_COMDAT_Selection_Kind_ ## n,+LLVM_HS_FOR_EACH_COMDAT_SELECTION_KIND(ENUM_CASE)+#undef ENUM_CASE+} LLVM_Hs_COMDAT_Selection_Kind;++#define LLVM_HS_FOR_EACH_DLL_STORAGE_CLASS(macro)	\+	macro(Default)                                        \+	macro(DLLImport)                                      \+	macro(DLLExport)++#define LLVM_HS_FOR_EACH_THREAD_LOCAL_MODE(macro)  \+	macro(NotThreadLocal)                                 \+	macro(GeneralDynamicTLSModel)                         \+	macro(LocalDynamicTLSModel)                           \+	macro(InitialExecTLSModel)                            \+	macro(LocalExecTLSModel)++#define LLVM_HS_FOR_EACH_UNNAMED_ADDR(macro) \+	macro(None)                                   \+	macro(Local)                                  \+	macro(Global)++typedef enum {+#define ENUM_CASE(x) LLVMUnnamedAddr ## x,+LLVM_HS_FOR_EACH_UNNAMED_ADDR(ENUM_CASE)+#undef ENUM_CASE+} LLVMUnnamedAddr;++#endif
+ src/LLVM/Internal/FFI/GlobalValue.hs view
@@ -0,0 +1,79 @@+{-# LANGUAGE+  ForeignFunctionInterface,+  MultiParamTypeClasses,+  UndecidableInstances+  #-}+-- | FFI functions for handling the LLVM GlobalValue class+module LLVM.Internal.FFI.GlobalValue where++import LLVM.Prelude++import Foreign.Ptr+import Foreign.C++import LLVM.Internal.FFI.PtrHierarchy+import LLVM.Internal.FFI.LLVMCTypes++data COMDAT++foreign import ccall unsafe "LLVMIsAGlobalValue" isAGlobalValue ::+  Ptr Value -> IO (Ptr GlobalValue)++foreign import ccall unsafe "LLVMGetLinkage" getLinkage ::+  Ptr GlobalValue -> IO Linkage++foreign import ccall unsafe "LLVMSetLinkage" setLinkage ::+  Ptr GlobalValue -> Linkage -> IO ()++foreign import ccall unsafe "LLVM_Hs_GetSection" getSection ::+  Ptr GlobalValue -> Ptr CSize -> IO CString++foreign import ccall unsafe "LLVMSetSection" setSection ::+  Ptr GlobalValue -> CString -> IO ()++foreign import ccall unsafe "LLVM_Hs_GetCOMDAT" getCOMDAT ::+  Ptr GlobalValue -> IO (Ptr COMDAT)++foreign import ccall unsafe "LLVM_Hs_SetCOMDAT" setCOMDAT ::+  Ptr GlobalObject -> Ptr COMDAT -> IO ()++foreign import ccall unsafe "LLVM_Hs_GetCOMDATName" getCOMDATName ::+  Ptr COMDAT -> Ptr CSize -> IO (Ptr CChar)++foreign import ccall unsafe "LLVM_Hs_GetCOMDATSelectionKind" getCOMDATSelectionKind ::+  Ptr COMDAT -> IO COMDATSelectionKind++foreign import ccall unsafe "LLVM_Hs_SetCOMDATSelectionKind" setCOMDATSelectionKind ::+  Ptr COMDAT -> COMDATSelectionKind -> IO ()++foreign import ccall unsafe "LLVMGetVisibility" getVisibility ::+  Ptr GlobalValue -> IO Visibility++foreign import ccall unsafe "LLVMSetVisibility" setVisibility ::+  Ptr GlobalValue -> Visibility -> IO ()++foreign import ccall unsafe "LLVMGetDLLStorageClass" getDLLStorageClass ::+  Ptr GlobalValue -> IO DLLStorageClass++foreign import ccall unsafe "LLVMSetDLLStorageClass" setDLLStorageClass ::+  Ptr GlobalValue -> DLLStorageClass -> IO ()++foreign import ccall unsafe "LLVMGetAlignment" getAlignment ::+  Ptr GlobalValue -> IO CUInt++foreign import ccall unsafe "LLVMSetAlignment" setAlignment ::+  Ptr GlobalValue -> CUInt -> IO ()++foreign import ccall unsafe "LLVM_Hs_GetUnnamedAddr" getUnnamedAddr ::+  Ptr GlobalValue -> IO UnnamedAddr++foreign import ccall unsafe "LLVM_Hs_SetUnnamedAddr" setUnnamedAddr ::+  Ptr GlobalValue -> UnnamedAddr -> IO ()++foreign import ccall unsafe "LLVM_Hs_GetThreadLocalMode" getThreadLocalMode ::+  Ptr GlobalValue -> IO ThreadLocalMode++foreign import ccall unsafe "LLVM_Hs_SetThreadLocalMode" setThreadLocalMode ::+  Ptr GlobalValue -> ThreadLocalMode -> IO ()++
+ src/LLVM/Internal/FFI/GlobalValueC.cpp view
@@ -0,0 +1,87 @@+#define __STDC_LIMIT_MACROS+#include "llvm/IR/Comdat.h"+#include "llvm/IR/GlobalValue.h"+#include "llvm/IR/GlobalObject.h"+#include "llvm-c/Core.h"+#include "LLVM/Internal/FFI/GlobalValue.h"++using namespace llvm;++extern "C" {++const Comdat *LLVM_Hs_GetCOMDAT(LLVMValueRef globalVal) {+  return unwrap<GlobalValue>(globalVal)->getComdat();+}++void LLVM_Hs_SetCOMDAT(LLVMValueRef globalObj, Comdat *comdat) {+  return unwrap<GlobalObject>(globalObj)->setComdat(comdat);+}++const char *LLVM_Hs_GetCOMDATName(const Comdat &comdat, size_t &size) {+  StringRef ref = comdat.getName();+  size = ref.size();+  return ref.data();+}++#define ENUM_CASE(n)                                                           \+    static_assert(unsigned(Comdat::n) ==                                       \+                      unsigned(LLVM_Hs_COMDAT_Selection_Kind_##n),        \+                  "COMDAT SelectionKind Enum mismatch");+LLVM_HS_FOR_EACH_COMDAT_SELECTION_KIND(ENUM_CASE)+#undef ENUM_CASE++const char* LLVM_Hs_GetSection(LLVMValueRef globalVal, size_t* strLength) {+    const auto& section = unwrap<GlobalValue>(globalVal)->getSection();+    *strLength = section.size();+    return section.data();+}++unsigned LLVM_Hs_GetCOMDATSelectionKind(const Comdat &comdat) {+  return unsigned(comdat.getSelectionKind());+}++void LLVM_Hs_SetCOMDATSelectionKind(Comdat &comdat, unsigned csk) {+  comdat.setSelectionKind(Comdat::SelectionKind(csk));+}++static LLVMUnnamedAddr unwrap(GlobalValue::UnnamedAddr a) {+    switch (a) {+#define ENUM_CASE(x) case GlobalValue::UnnamedAddr::x: return LLVMUnnamedAddr ## x;+LLVM_HS_FOR_EACH_UNNAMED_ADDR(ENUM_CASE)+#undef ENUM_CASE+    default: return LLVMUnnamedAddrNone;+    }+}++static GlobalValue::UnnamedAddr wrap(LLVMUnnamedAddr a) {+    switch (a) {+#define ENUM_CASE(x) case LLVMUnnamedAddr ## x: return GlobalValue::UnnamedAddr::x;+LLVM_HS_FOR_EACH_UNNAMED_ADDR(ENUM_CASE)+#undef ENUM_CASE+    default: return GlobalValue::UnnamedAddr::None;+    }+}++LLVMUnnamedAddr LLVM_Hs_GetUnnamedAddr(LLVMValueRef globalVal) {+    return unwrap(unwrap<GlobalValue>(globalVal)->getUnnamedAddr());+}++void LLVM_Hs_SetUnnamedAddr(LLVMValueRef globalVal, LLVMUnnamedAddr attr) {+    unwrap<GlobalValue>(globalVal)->setUnnamedAddr(wrap(attr));+}++#define ENUM_CASE(n)                                                           \+    static_assert(unsigned(GlobalValue::n) == unsigned(LLVM##n),               \+                  "TLS Model Enum mismatch");+LLVM_HS_FOR_EACH_THREAD_LOCAL_MODE(ENUM_CASE)+#undef ENUM_CASE++LLVMThreadLocalMode LLVM_Hs_GetThreadLocalMode(LLVMValueRef globalVal) {+    return LLVMThreadLocalMode(unwrap<GlobalValue>(globalVal)->getThreadLocalMode());+}++void LLVM_Hs_SetThreadLocalMode(LLVMValueRef globalVal, LLVMThreadLocalMode mode) {+    unwrap<GlobalValue>(globalVal)->setThreadLocalMode(GlobalValue::ThreadLocalMode(mode));+}++}
+ src/LLVM/Internal/FFI/GlobalVariable.hs view
@@ -0,0 +1,31 @@+{-# LANGUAGE+  ForeignFunctionInterface,+  MultiParamTypeClasses,+  UndecidableInstances+  #-}+-- | FFI functions for handling the LLVM GlobalVariable class+module LLVM.Internal.FFI.GlobalVariable where++import LLVM.Prelude++import Foreign.Ptr+import Foreign.C++import LLVM.Internal.FFI.PtrHierarchy+import LLVM.Internal.FFI.LLVMCTypes++foreign import ccall unsafe "LLVMIsAGlobalVariable" isAGlobalVariable ::+    Ptr Value -> IO (Ptr GlobalVariable)++foreign import ccall unsafe "LLVMIsGlobalConstant" isGlobalConstant ::+    Ptr GlobalVariable -> IO LLVMBool++foreign import ccall unsafe "LLVMSetGlobalConstant" setGlobalConstant ::+    Ptr GlobalVariable -> LLVMBool -> IO ()++foreign import ccall unsafe "LLVMGetInitializer" getInitializer ::+    Ptr GlobalVariable -> IO (Ptr Constant)++foreign import ccall unsafe "LLVMSetInitializer" setInitializer ::+    Ptr GlobalVariable -> Ptr Constant -> IO ()+
+ src/LLVM/Internal/FFI/InlineAssembly.h view
@@ -0,0 +1,14 @@+#ifndef __LLVM_INTERNAL_FFI__INLINE_ASSEMBLY__H__+#define __LLVM_INTERNAL_FFI__INLINE_ASSEMBLY__H__++#define LLVM_HS_FOR_EACH_ASM_DIALECT(macro) \+	macro(ATT) \+	macro(Intel) \++typedef enum {+#define ENUM_CASE(d) LLVMAsmDialect_ ## d,+	LLVM_HS_FOR_EACH_ASM_DIALECT(ENUM_CASE)+#undef ENUM_CASE+} LLVMAsmDialect;++#endif
+ src/LLVM/Internal/FFI/InlineAssembly.hs view
@@ -0,0 +1,35 @@+{-# LANGUAGE+  ForeignFunctionInterface+  #-}++module LLVM.Internal.FFI.InlineAssembly where++import LLVM.Prelude++import Foreign.C+import Foreign.Ptr++import LLVM.Internal.FFI.LLVMCTypes+import LLVM.Internal.FFI.PtrHierarchy++foreign import ccall unsafe "LLVMIsAInlineAsm" isAInlineAsm ::+  Ptr Value -> IO (Ptr InlineAsm)++foreign import ccall unsafe "LLVM_Hs_CreateInlineAsm" createInlineAsm ::+  Ptr Type -> CString -> CString -> LLVMBool -> LLVMBool -> AsmDialect -> IO (Ptr InlineAsm)++foreign import ccall unsafe "LLVM_Hs_GetInlineAsmAsmString" getInlineAsmAssemblyString ::+  Ptr InlineAsm -> IO CString++foreign import ccall unsafe "LLVM_Hs_GetInlineAsmConstraintString" getInlineAsmConstraintString ::+  Ptr InlineAsm -> IO CString++foreign import ccall unsafe "LLVM_Hs_InlineAsmHasSideEffects" inlineAsmHasSideEffects ::+  Ptr InlineAsm -> IO LLVMBool++foreign import ccall unsafe "LLVM_Hs_InlineAsmIsAlignStack" inlineAsmIsAlignStack ::+  Ptr InlineAsm -> IO LLVMBool++foreign import ccall unsafe "LLVM_Hs_GetInlineAsmDialect" getInlineAsmDialect ::+  Ptr InlineAsm -> IO AsmDialect+
+ src/LLVM/Internal/FFI/InlineAssemblyC.cpp view
@@ -0,0 +1,73 @@+#define __STDC_LIMIT_MACROS+#include "llvm/IR/InlineAsm.h"+#include "llvm/IR/Function.h"+#include "llvm-c/Core.h"++#include "LLVM/Internal/FFI/InlineAssembly.h"++using namespace llvm;++namespace llvm {+static LLVMAsmDialect wrap(InlineAsm::AsmDialect d) {+	switch(d) {+#define ENUM_CASE(x) case InlineAsm::AD_ ## x: return LLVMAsmDialect_ ## x;+LLVM_HS_FOR_EACH_ASM_DIALECT(ENUM_CASE)+#undef ENUM_CASE+	default: return LLVMAsmDialect(0);+	}+}++static InlineAsm::AsmDialect unwrap(LLVMAsmDialect d) {+	switch(d) {+#define ENUM_CASE(x) case LLVMAsmDialect_ ## x: return InlineAsm::AD_ ## x;+LLVM_HS_FOR_EACH_ASM_DIALECT(ENUM_CASE)+#undef ENUM_CASE+	default: return InlineAsm::AsmDialect(0);+	}+}+}++extern "C" {++LLVMValueRef LLVM_Hs_CreateInlineAsm(+	LLVMTypeRef t,+	const char *asmStr,+	const char *constraintsStr,+	LLVMBool hasSideEffects,+	LLVMBool isAlignStack,+	LLVMAsmDialect dialect+) {+	return wrap(+		InlineAsm::get(+			unwrap<FunctionType>(t), +			asmStr,+			constraintsStr,+			hasSideEffects,+			isAlignStack,+			unwrap(dialect)+		)+	);+}++const char *LLVM_Hs_GetInlineAsmAsmString(LLVMValueRef v) {+	return unwrap<InlineAsm>(v)->getAsmString().c_str();+}++const char *LLVM_Hs_GetInlineAsmConstraintString(LLVMValueRef v) {+	return unwrap<InlineAsm>(v)->getConstraintString().c_str();+}++LLVMBool LLVM_Hs_InlineAsmHasSideEffects(LLVMValueRef v) {+	return unwrap<InlineAsm>(v)->hasSideEffects();+}++LLVMBool LLVM_Hs_InlineAsmIsAlignStack(LLVMValueRef v) {+	return unwrap<InlineAsm>(v)->isAlignStack();+}++LLVMAsmDialect LLVM_Hs_GetInlineAsmDialect(LLVMValueRef v) {+	return wrap(unwrap<InlineAsm>(v)->getDialect());+}++}+
+ src/LLVM/Internal/FFI/Instruction.h view
@@ -0,0 +1,67 @@+#ifndef __LLVM_INTERNAL_FFI__INSTRUCTION__H__+#define __LLVM_INTERNAL_FFI__INSTRUCTION__H__++#include "llvm/Config/llvm-config.h"++#define LLVM_HS_FOR_EACH_ATOMIC_ORDERING(macro) \+	macro(NotAtomic) \+	macro(Unordered) \+	macro(Monotonic) \+	macro(Acquire) \+	macro(Release) \+	macro(AcquireRelease) \+	macro(SequentiallyConsistent)++#define LLVM_HS_FOR_EACH_RMW_OPERATION(macro) \+	macro(Xchg) \+	macro(Add) \+	macro(Sub) \+	macro(And) \+	macro(Nand) \+	macro(Or) \+	macro(Xor) \+	macro(Max) \+	macro(Min) \+	macro(UMax) \+	macro(UMin)++#define LLVM_HS_FOR_EACH_SYNCRONIZATION_SCOPE(macro) \+	macro(SingleThread) \+	macro(CrossThread)++typedef enum {+#define ENUM_CASE(x) LLVM ## x ## SynchronizationScope,+LLVM_HS_FOR_EACH_SYNCRONIZATION_SCOPE(ENUM_CASE)+#undef ENUM_CASE+} LLVMSynchronizationScope;++#define LLVM_HS_FOR_EACH_FAST_MATH_FLAG(macro) \+	macro(UnsafeAlgebra, unsafeAlgebra)								\+	macro(NoNaNs, noNaNs)															\+	macro(NoInfs, noInfs)															\+	macro(NoSignedZeros, noSignedZeros)								\+	macro(AllowReciprocal, allowReciprocal)++typedef enum {+#define ENUM_CASE(x,l) LLVM ## x ## Bit,+LLVM_HS_FOR_EACH_FAST_MATH_FLAG(ENUM_CASE)+#undef ENUM_CASE+} LLVMFastMathFlagBit;++typedef enum {+#define ENUM_CASE(x,l) LLVM ## x = (1 << LLVM ## x ## Bit),+LLVM_HS_FOR_EACH_FAST_MATH_FLAG(ENUM_CASE)+#undef ENUM_CASE+} LLVMFastMathFlags;++#define LLVM_HS_FOR_EACH_TAIL_CALL_KIND(macro) \+	macro(None)                                       \+	macro(Tail)                                       \+	macro(MustTail)++typedef enum {+#define ENUM_CASE(x) LLVM_Hs_TailCallKind_ ## x,+LLVM_HS_FOR_EACH_TAIL_CALL_KIND(ENUM_CASE)+#undef ENUM_CASE+} LLVM_Hs_TailCallKind;+#endif
+ src/LLVM/Internal/FFI/Instruction.hs view
@@ -0,0 +1,181 @@+{-# LANGUAGE+  ForeignFunctionInterface,+  MultiParamTypeClasses,+  UndecidableInstances,+  TemplateHaskell+  #-}+module LLVM.Internal.FFI.Instruction where++import LLVM.Prelude++import Foreign.Ptr+import Foreign.C++import LLVM.Internal.FFI.Attribute+import LLVM.Internal.FFI.PtrHierarchy+import LLVM.Internal.FFI.LLVMCTypes++foreign import ccall unsafe "LLVMIsAInstruction" isAInstruction ::+  Ptr Value -> IO (Ptr Instruction)++newtype COpcode = COpcode CUInt++-- get the C API opcode+foreign import ccall unsafe "LLVMGetInstructionOpcode" getInstructionOpcode :: +  Ptr Instruction -> IO COpcode++-- get the C++ API opcode (one less level of mapping than for that from the C API)+foreign import ccall unsafe "LLVM_Hs_GetInstructionDefOpcode" getInstructionDefOpcode :: +  Ptr Instruction -> IO CPPOpcode++foreign import ccall unsafe "LLVMGetICmpPredicate" getICmpPredicate ::+  Ptr Instruction -> IO ICmpPredicate++foreign import ccall unsafe "LLVM_Hs_GetFCmpPredicate" getFCmpPredicate ::+  Ptr Instruction -> IO FCmpPredicate++foreign import ccall unsafe "LLVM_Hs_GetCallSiteCallingConvention" getCallSiteCallingConvention ::+  Ptr Instruction -> IO CallingConvention++foreign import ccall unsafe "LLVM_Hs_SetCallSiteCallingConvention" setCallSiteCallingConvention ::+  Ptr Instruction -> CallingConvention -> IO ()++foreign import ccall unsafe "LLVM_Hs_GetTailCallKind" getTailCallKind ::+  Ptr Instruction -> IO TailCallKind++foreign import ccall unsafe "LLVM_Hs_SetTailCallKind" setTailCallKind ::+  Ptr Instruction -> TailCallKind -> IO ()++foreign import ccall unsafe "LLVM_Hs_GetCallSiteCalledValue" getCallSiteCalledValue ::+  Ptr Instruction -> IO (Ptr Value)++foreign import ccall unsafe "LLVM_Hs_GetCallSiteAttributeSet" getCallSiteAttributeSet ::+  Ptr Instruction -> IO MixedAttributeSet++foreign import ccall unsafe "LLVM_Hs_SetCallSiteAttributeSet" setCallSiteAttributeSet ::+  Ptr Instruction -> MixedAttributeSet -> IO ()+                     +foreign import ccall unsafe "LLVMAddIncoming" addIncoming' ::+  Ptr Instruction -> Ptr (Ptr Value) -> Ptr (Ptr BasicBlock) -> CUInt -> IO ()++addIncoming :: Ptr Instruction -> (CUInt, Ptr (Ptr Value)) -> (CUInt, Ptr (Ptr BasicBlock)) -> IO ()+addIncoming i (nvs, vs) (nbs, bs) | nbs == nvs = addIncoming' i vs bs nbs++foreign import ccall unsafe "LLVMCountIncoming" countIncoming ::+  Ptr Instruction -> IO CUInt++foreign import ccall unsafe "LLVMGetIncomingValue" getIncomingValue ::+  Ptr Instruction -> CUInt -> IO (Ptr Value)++foreign import ccall unsafe "LLVMGetIncomingBlock" getIncomingBlock ::+  Ptr Instruction -> CUInt -> IO (Ptr BasicBlock)+++foreign import ccall unsafe "LLVMAddCase" addCase ::+  Ptr Instruction -> Ptr Constant -> Ptr BasicBlock -> IO ()++foreign import ccall unsafe "LLVM_Hs_GetSwitchCases" getSwitchCases ::+  Ptr Instruction -> Ptr (Ptr Constant) -> Ptr (Ptr BasicBlock) -> IO ()++foreign import ccall unsafe "LLVMAddDestination" addDestination ::+  Ptr Instruction -> Ptr BasicBlock -> IO ()++foreign import ccall unsafe "LLVM_Hs_GetIndirectBrDests" getIndirectBrDests ::+  Ptr Instruction -> Ptr (Ptr BasicBlock) -> IO ()+++foreign import ccall unsafe "LLVM_Hs_GetInstrAlignment" getInstrAlignment ::+  Ptr Instruction -> IO CUInt++foreign import ccall unsafe "LLVM_Hs_SetInstrAlignment" setInstrAlignment ::+  Ptr Instruction -> CUInt -> IO ()++foreign import ccall unsafe "LLVM_Hs_GetAllocaNumElements" getAllocaNumElements ::+  Ptr Instruction -> IO (Ptr Value)++foreign import ccall unsafe "LLVM_Hs_GetAllocatedType" getAllocatedType ::+  Ptr Instruction -> IO (Ptr Type)++foreign import ccall unsafe "LLVM_Hs_GetAtomicOrdering" getAtomicOrdering ::+  Ptr Instruction -> IO MemoryOrdering++foreign import ccall unsafe "LLVM_Hs_GetFailureAtomicOrdering" getFailureAtomicOrdering ::+  Ptr Instruction -> IO MemoryOrdering++foreign import ccall unsafe "LLVM_Hs_GetSynchronizationScope" getSynchronizationScope ::+  Ptr Instruction -> IO SynchronizationScope++getAtomicity :: Ptr Instruction -> IO (SynchronizationScope, MemoryOrdering)+getAtomicity i = return (,) `ap` getSynchronizationScope i `ap` getAtomicOrdering i++foreign import ccall unsafe "LLVM_Hs_GetVolatile" getVolatile ::+  Ptr Instruction -> IO LLVMBool++foreign import ccall unsafe "LLVM_Hs_GetInBounds" getInBounds ::+  Ptr Value -> IO LLVMBool++foreign import ccall unsafe "LLVM_Hs_GetAtomicRMWBinOp" getAtomicRMWBinOp ::+  Ptr Instruction -> IO RMWOperation++foreign import ccall unsafe "LLVM_Hs_CountInstStructureIndices" countInstStructureIndices ::+  Ptr Instruction -> IO CUInt++foreign import ccall unsafe "LLVM_Hs_GetInstStructureIndices" getInstStructureIndices ::+  Ptr Instruction -> Ptr CUInt -> IO ()++foreign import ccall unsafe "LLVMAddClause" addClause ::+  Ptr Instruction -> Ptr Constant -> IO ()++foreign import ccall unsafe "LLVMSetCleanup" setCleanup ::+  Ptr Instruction -> LLVMBool -> IO ()++foreign import ccall unsafe "LLVMIsCleanup" isCleanup ::+  Ptr Instruction -> IO LLVMBool++foreign import ccall unsafe "LLVMGetNumClauses" getNumClauses ::+  Ptr Instruction -> IO CUInt++foreign import ccall unsafe "LLVMGetClause" getClause ::+  Ptr Instruction -> CUInt -> IO (Ptr Constant)++foreign import ccall unsafe "LLVM_Hs_SetMetadata" setMetadata ::+  Ptr Instruction -> MDKindID -> Ptr MDNode -> IO ()++foreign import ccall unsafe "LLVM_Hs_GetMetadata" getMetadata ::+  Ptr Instruction -> Ptr MDKindID -> Ptr (Ptr MDNode) -> CUInt -> IO CUInt++foreign import ccall unsafe "LLVM_Hs_GetCleanupPad" getCleanupPad ::+  Ptr Instruction -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVM_Hs_GetUnwindDest" getUnwindDest ::+  Ptr Instruction -> IO (Ptr BasicBlock)++foreign import ccall unsafe "LLVM_Hs_GetParentPad" getParentPad ::+  Ptr Instruction -> IO (Ptr Value)++foreign import ccall unsafe "LLVM_Hs_GetNumArgOperands" getNumArgOperands ::+  Ptr Instruction -> IO CUInt++foreign import ccall unsafe "LLVM_Hs_GetArgOperand" getArgOperand ::+  Ptr Instruction -> CUInt -> IO (Ptr Value)++foreign import ccall unsafe "LLVM_Hs_CatchSwitch_GetParentPad" catchSwitchGetParentPad ::+  Ptr Instruction -> IO (Ptr Value)++foreign import ccall unsafe "LLVM_Hs_CatchSwitch_GetUnwindDest" catchSwitchGetUnwindDest ::+  Ptr Instruction -> IO (Ptr BasicBlock)++foreign import ccall unsafe "LLVM_Hs_CatchSwitch_GetNumHandlers" catchSwitchGetNumHandlers ::+  Ptr Instruction -> IO CUInt++foreign import ccall unsafe "LLVM_Hs_CatchSwitch_GetHandler" catchSwitchGetHandler ::+  Ptr Instruction -> CUInt -> IO (Ptr BasicBlock)++foreign import ccall unsafe "LLVM_Hs_CatchSwitch_AddHandler" catchSwitchAddHandler ::+  Ptr Instruction -> Ptr BasicBlock -> IO ()++foreign import ccall unsafe "LLVM_Hs_CatchRet_GetCatchPad" catchRetGetCatchPad ::+  Ptr Instruction -> IO (Ptr Value)++foreign import ccall unsafe "LLVM_Hs_CatchRet_GetSuccessor" catchRetGetSuccessor ::+  Ptr Instruction -> IO (Ptr BasicBlock)
+ src/LLVM/Internal/FFI/InstructionC.cpp view
@@ -0,0 +1,323 @@+#define __STDC_LIMIT_MACROS+#include "llvm/Config/llvm-config.h"+#include "llvm/IR/LLVMContext.h"+#include "llvm/IR/InstrTypes.h"+#include "llvm/IR/Attributes.h"+#include "llvm/IR/Operator.h"+#include "llvm/IR/BasicBlock.h"+#include "llvm/IR/Metadata.h"+#include "llvm/IR/CallSite.h"++#include "llvm-c/Core.h"++#include "LLVM/Internal/FFI/Metadata.hpp"+#include "LLVM/Internal/FFI/AttributeC.hpp"+#include "LLVM/Internal/FFI/Instruction.h"++using namespace llvm;++namespace llvm {++static LLVMAtomicOrdering wrap(AtomicOrdering l) {+	switch(l) {+#define ENUM_CASE(x) case AtomicOrdering::x: return LLVMAtomicOrdering ## x;+LLVM_HS_FOR_EACH_ATOMIC_ORDERING(ENUM_CASE)+#undef ENUM_CASE+	default: return LLVMAtomicOrdering(0);+	}+}++static LLVMSynchronizationScope wrap(SynchronizationScope l) {+	switch(l) {+#define ENUM_CASE(x) case x: return LLVM ## x ## SynchronizationScope;+LLVM_HS_FOR_EACH_SYNCRONIZATION_SCOPE(ENUM_CASE)+#undef ENUM_CASE+	default: return LLVMSynchronizationScope(0);+	}+}++static LLVMAtomicRMWBinOp wrap(AtomicRMWInst::BinOp l) {+	switch(l) {+#define ENUM_CASE(x) case AtomicRMWInst::x: return LLVMAtomicRMWBinOp ## x;+LLVM_HS_FOR_EACH_RMW_OPERATION(ENUM_CASE)+#undef ENUM_CASE+	default: return LLVMAtomicRMWBinOp(0);+	}+}++LLVMFastMathFlags wrap(FastMathFlags f) {+	unsigned r = 0;+#define ENUM_CASE(u,l) if (f.l()) r |= unsigned(LLVM ## u);+LLVM_HS_FOR_EACH_FAST_MATH_FLAG(ENUM_CASE)+#undef ENUM_CASE+	return LLVMFastMathFlags(r);+}++}++extern "C" {++unsigned LLVM_Hs_GetInstructionDefOpcode(LLVMValueRef val) {+	return unwrap<Instruction>(val)->getOpcode();+}++unsigned LLVM_Hs_HasNoSignedWrap(LLVMValueRef val) {+	return unwrap<OverflowingBinaryOperator>(val)->hasNoSignedWrap();+}++unsigned LLVM_Hs_HasNoUnsignedWrap(LLVMValueRef val) {+	return unwrap<OverflowingBinaryOperator>(val)->hasNoUnsignedWrap();+}++int LLVM_Hs_IsExact(LLVMValueRef val) {+	return unwrap<PossiblyExactOperator>(val)->isExact();+}++LLVMFastMathFlags LLVM_Hs_GetFastMathFlags(LLVMValueRef val) {+	return wrap(unwrap<Instruction>(val)->getFastMathFlags());+}++LLVMValueRef LLVM_Hs_GetCallSiteCalledValue(LLVMValueRef i) {+	return wrap(CallSite(unwrap<Instruction>(i)).getCalledValue());+}++const AttributeSetImpl *LLVM_Hs_GetCallSiteAttributeSet(LLVMValueRef i) {+	return wrap(CallSite(unwrap<Instruction>(i)).getAttributes());+}++void LLVM_Hs_SetCallSiteAttributeSet(LLVMValueRef i, const AttributeSetImpl *asi) {+	CallSite(unwrap<Instruction>(i)).setAttributes(unwrap(asi));+}++unsigned LLVM_Hs_GetCallSiteCallingConvention(LLVMValueRef i) {+  return unsigned(CallSite(unwrap<Instruction>(i)).getCallingConv());+}++void LLVM_Hs_SetCallSiteCallingConvention(LLVMValueRef i, unsigned cc) {+  CallSite(unwrap<Instruction>(i)).setCallingConv(llvm::CallingConv::ID(cc));+}++#define CHECK(name)                                                            \+    static_assert(unsigned(llvm::CallInst::TCK_##name) ==                      \+                      unsigned(LLVM_Hs_TailCallKind_##name),              \+                  "LLVM_Hs_TailCallKind enum out of sync w/ "             \+                  "llvm::CallInst::TailCallKind for " #name);+LLVM_HS_FOR_EACH_TAIL_CALL_KIND(CHECK)+#undef CHECK++unsigned LLVM_Hs_GetTailCallKind(LLVMValueRef i) {+    return unwrap<CallInst>(i)->getTailCallKind();+}++void LLVM_Hs_SetTailCallKind(LLVMValueRef i, unsigned kind) {+    return unwrap<CallInst>(i)->setTailCallKind(llvm::CallInst::TailCallKind(kind));+}++LLVMValueRef LLVM_Hs_GetAllocaNumElements(LLVMValueRef a) {+	return wrap(unwrap<AllocaInst>(a)->getArraySize());+}++LLVMTypeRef LLVM_Hs_GetAllocatedType(LLVMValueRef a) {+	return wrap(unwrap<AllocaInst>(a)->getAllocatedType());+}++// ------------------------------------------------------------++#define LLVM_HS_FOR_EACH_ALIGNMENT_INST(macro) \+	macro(Alloca) \+	macro(Load) \+	macro(Store)++unsigned LLVM_Hs_GetInstrAlignment(LLVMValueRef l) {+	switch(unwrap<Instruction>(l)->getOpcode()) {+#define ENUM_CASE(n) case Instruction::n: return unwrap<n ## Inst>(l)->getAlignment();+		LLVM_HS_FOR_EACH_ALIGNMENT_INST(ENUM_CASE)+#undef ENUM_CASE+	default: return 0;+	}+}++void LLVM_Hs_SetInstrAlignment(LLVMValueRef l, unsigned a) {+	switch(unwrap<Instruction>(l)->getOpcode()) {+#define ENUM_CASE(n) case Instruction::n: unwrap<n ## Inst>(l)->setAlignment(a); break;+		LLVM_HS_FOR_EACH_ALIGNMENT_INST(ENUM_CASE)+#undef ENUM_CASE+	}+}++// ------------------------------------------------------------++#define LLVM_HS_FOR_EACH_ATOMIC_INST(macro)	\+	macro(Load,)																		\+	macro(Store,)																		\+	macro(Fence,)																		\+	macro(AtomicCmpXchg,Success)										\+	macro(AtomicRMW,)++LLVMAtomicOrdering LLVM_Hs_GetAtomicOrdering(LLVMValueRef i) {+	switch(unwrap<Instruction>(i)->getOpcode()) {+#define ENUM_CASE(n,s) case Instruction::n: return wrap(unwrap<n ## Inst>(i)->get ## s ## Ordering());+		LLVM_HS_FOR_EACH_ATOMIC_INST(ENUM_CASE)+#undef ENUM_CASE+	default: return LLVMAtomicOrdering(0);+	}+}++LLVMAtomicOrdering LLVM_Hs_GetFailureAtomicOrdering(LLVMValueRef i) {+	switch(unwrap<Instruction>(i)->getOpcode()) {+	case Instruction::AtomicCmpXchg: return wrap(unwrap<AtomicCmpXchgInst>(i)->getFailureOrdering());+	default: return LLVMAtomicOrdering(0);+	}+}++LLVMSynchronizationScope LLVM_Hs_GetSynchronizationScope(LLVMValueRef i) {+	switch(unwrap<Instruction>(i)->getOpcode()) {+#define ENUM_CASE(n,s) case Instruction::n: return wrap(unwrap<n ## Inst>(i)->getSynchScope());+		LLVM_HS_FOR_EACH_ATOMIC_INST(ENUM_CASE)+#undef ENUM_CASE+	default: return LLVMSynchronizationScope(0);+	}+}++#define LLVM_HS_FOR_EACH_VOLATILITY_INST(macro) \+	macro(Load) \+	macro(Store) \+	macro(AtomicCmpXchg) \+	macro(AtomicRMW)++LLVMBool LLVM_Hs_GetVolatile(LLVMValueRef i) {+	switch(unwrap<Instruction>(i)->getOpcode()) {+#define ENUM_CASE(n) case Instruction::n: return unwrap<n ## Inst>(i)->isVolatile();+		LLVM_HS_FOR_EACH_VOLATILITY_INST(ENUM_CASE)+#undef ENUM_CASE+	default: return LLVMBool(0);+	}+}++// ------------------------------------------------------------++LLVMBool LLVM_Hs_GetInBounds(LLVMValueRef i) {+	return unwrap<GEPOperator>(i)->isInBounds();+}++LLVMAtomicRMWBinOp LLVM_Hs_GetAtomicRMWBinOp(LLVMValueRef i) {+	return wrap(unwrap<AtomicRMWInst>(i)->getOperation());+}++LLVMRealPredicate LLVM_Hs_GetFCmpPredicate(LLVMValueRef Inst) {+	if (FCmpInst *I = dyn_cast<FCmpInst>(unwrap(Inst)))+		return (LLVMRealPredicate)I->getPredicate();+	if (ConstantExpr *CE = dyn_cast<ConstantExpr>(unwrap(Inst)))+		if (CE->getOpcode() == Instruction::FCmp)+			return (LLVMRealPredicate)CE->getPredicate();+	return (LLVMRealPredicate)0;+}++unsigned LLVM_Hs_CountInstStructureIndices(LLVMValueRef v) {+	if (ExtractValueInst *i = dyn_cast<ExtractValueInst>(unwrap(v))) return i->getNumIndices();+	if (InsertValueInst *i = dyn_cast<InsertValueInst>(unwrap(v))) return i->getNumIndices();+	return 0;+}++void LLVM_Hs_GetInstStructureIndices(LLVMValueRef v, unsigned *is) {+	ArrayRef<unsigned> a;+	if (ExtractValueInst *i = dyn_cast<ExtractValueInst>(unwrap(v))) a = i->getIndices();+	if (InsertValueInst *i = dyn_cast<InsertValueInst>(unwrap(v))) a = i->getIndices();+	std::copy(a.begin(), a.end(), is);+}++void LLVM_Hs_GetSwitchCases(+	LLVMValueRef v,+	LLVMValueRef *values,+	LLVMBasicBlockRef *dests+) {+	SwitchInst *s = unwrap<SwitchInst>(v);+	for(SwitchInst::CaseIt i = s->case_begin(); i != s->case_end(); ++i, ++values, ++dests) {+		*values = wrap(i.getCaseValue());+		*dests = wrap(i.getCaseSuccessor());+	}+}++void LLVM_Hs_GetIndirectBrDests(+	LLVMValueRef v,+	LLVMBasicBlockRef *dests+) {+	IndirectBrInst *ib = unwrap<IndirectBrInst>(v);+	for(unsigned i=0; i != ib->getNumDestinations(); ++i, ++dests)+		*dests = wrap(ib->getDestination(i));+}++inline Metadata **unwrap(LLVMMetadataRef *vals) {+    return reinterpret_cast<Metadata**>(vals);+}++void LLVM_Hs_SetMetadata(LLVMValueRef inst, unsigned kindID, LLVMMetadataRef md) {+    MDNode *N = md ? unwrap<MDNode>(md) : nullptr;+    unwrap<Instruction>(inst)->setMetadata(kindID, N);+}++unsigned LLVM_Hs_GetMetadata(+	LLVMValueRef i,+	unsigned *kinds,+	LLVMMetadataRef *nodes,+	unsigned nKinds+) {+	SmallVector<std::pair<unsigned, MDNode *>, 4> mds;+	unwrap<Instruction>(i)->getAllMetadata(mds);+	if (mds.size() <= nKinds) {+		for(unsigned i=0; i<mds.size(); ++i) {+			kinds[i] = mds[i].first;+			nodes[i] = wrap(mds[i].second);+		}+	}+	return mds.size();+}++LLVMValueRef LLVM_Hs_GetCleanupPad(LLVMValueRef i) {+    return wrap(unwrap<CleanupReturnInst>(i)->getCleanupPad());+}++LLVMBasicBlockRef LLVM_Hs_GetUnwindDest(LLVMValueRef i) {+    return wrap(unwrap<CleanupReturnInst>(i)->getUnwindDest());+}++LLVMValueRef LLVM_Hs_GetParentPad(LLVMValueRef i) {+    return wrap(unwrap<FuncletPadInst>(i)->getParentPad());+}++unsigned LLVM_Hs_GetNumArgOperands(LLVMValueRef i) {+    return unwrap<FuncletPadInst>(i)->getNumArgOperands();+}++LLVMValueRef LLVM_Hs_GetArgOperand(LLVMValueRef i, unsigned op) {+    return wrap(unwrap<FuncletPadInst>(i)->getArgOperand(op));+}++LLVMValueRef LLVM_Hs_CatchSwitch_GetParentPad(LLVMValueRef i) {+    return wrap(unwrap<CatchSwitchInst>(i)->getParentPad());+}++LLVMBasicBlockRef LLVM_Hs_CatchSwitch_GetUnwindDest(LLVMValueRef i) {+    return wrap(unwrap<CatchSwitchInst>(i)->getUnwindDest());+}++unsigned LLVM_Hs_CatchSwitch_GetNumHandlers(LLVMValueRef i) {+    return unwrap<CatchSwitchInst>(i)->getNumHandlers();+}++LLVMBasicBlockRef LLVM_Hs_CatchSwitch_GetHandler(LLVMValueRef instr, unsigned i) {+    return wrap(*(unwrap<CatchSwitchInst>(instr)->handler_begin() + i));+}++void LLVM_Hs_CatchSwitch_AddHandler(LLVMValueRef instr, LLVMBasicBlockRef bb) {+    unwrap<CatchSwitchInst>(instr)->addHandler(unwrap(bb));+}++LLVMValueRef LLVM_Hs_CatchRet_GetCatchPad(LLVMValueRef i) {+    return wrap(unwrap<CatchReturnInst>(i)->getCatchPad());+}++LLVMBasicBlockRef LLVM_Hs_CatchRet_GetSuccessor(LLVMValueRef i) {+    return wrap(unwrap<CatchReturnInst>(i)->getSuccessor());+}+}
+ src/LLVM/Internal/FFI/InstructionDefs.hsc view
@@ -0,0 +1,61 @@+-- This module translates the instruction data in "llvm/Instruction.def" into a Haskell data structure,+-- so it may be accessed conveniently with Template Haskell code+module LLVM.Internal.FFI.InstructionDefs where++import LLVM.Prelude++import LLVM.Internal.FFI.LLVMCTypes++#define FIRST_TERM_INST(num) struct inst { const char *kind; int opcode; const char *name; const char *clas; } insts[] = { { "Terminator", },++#define FIRST_BINARY_INST(num) { "Binary" },+#define FIRST_MEMORY_INST(num) { "Memory" },+#define FIRST_CAST_INST(num) { "Cast" },+#define FIRST_OTHER_INST(num) { "Other" },+#define FIRST_FUNCLETPAD_INST(num) { "FuncletPad" },++#define HANDLE_INST(num,opcode,class) { 0, num, #opcode, #class, },++#define LAST_OTHER_INST(num) { 0, 0, 0, 0, } };++#include "llvm/Config/llvm-config.h"++#include "llvm/IR/Instruction.def"++#{+define hsc_inject() {                                       \+  hsc_printf("[");                                       \+  struct inst *i;                                           \+  const char *kind;                                         \+  int first = 1;                                            \+  for(i = insts; i->kind || i->opcode; ++i) {               \+    if (i->kind) { kind = i->kind; continue; }              \+    if (!first) { hsc_printf("\n   ,"); } else { first = 0; }  \+    hsc_printf(                                             \+        " (CPPOpcode %d,\"%s\",\"%s\", %s)",               \+        i->opcode, i->name, i->clas, kind                   \+      );                                                    \+  }                                                         \+  hsc_printf(" ] ");                                       \+}+}++data InstructionKind = Terminator | Binary | Memory | Cast | FuncletPad | Other+  deriving (Eq, Ord, Show)++data InstructionDef = InstructionDef {+    cppOpcode :: CPPOpcode,+    cAPIName :: String,+    cAPIClassName :: String,+    instructionKind :: InstructionKind+  }+  deriving (Eq, Ord, Show)++instructionDefs :: [InstructionDef]+instructionDefs = [ + InstructionDef o an acn k+ | (o, an, acn, k) <-+   #{inject},+ an /= "UserOp1" && an /= "UserOp2"+ ]+
+ src/LLVM/Internal/FFI/Iterate.hs view
@@ -0,0 +1,13 @@+-- | Functions to help handle LLVM iteration patterns+module LLVM.Internal.FFI.Iterate where++import LLVM.Prelude++import Foreign.Ptr++-- | retrieve a sequence of objects which form a linked list, given an action to+-- | retrieve the first member and an action to proceed through the list+getXs :: IO (Ptr a) -> (Ptr a -> IO (Ptr a)) -> IO [Ptr a]+getXs firstX nextX = walk =<< firstX+    where walk x | x == nullPtr = return []+          walk x = (x:) <$> (walk <=< nextX) x
+ src/LLVM/Internal/FFI/LLVMCTypes.hsc view
@@ -0,0 +1,266 @@+{-# LANGUAGE+  GeneralizedNewtypeDeriving+  #-}+-- | Define types which correspond cleanly with some simple types on the C/C++ side.+-- Encapsulate hsc macro weirdness here, supporting higher-level tricks elsewhere.+module LLVM.Internal.FFI.LLVMCTypes where++import LLVM.Prelude++#define __STDC_LIMIT_MACROS+#include "llvm-c/Core.h"+#include "llvm-c/Linker.h"+#include "llvm-c/OrcBindings.h"+#include "llvm-c/Target.h"+#include "llvm-c/TargetMachine.h"+#include "LLVM/Internal/FFI/Attribute.h"+#include "LLVM/Internal/FFI/Instruction.h"+#include "LLVM/Internal/FFI/Value.h"+#include "LLVM/Internal/FFI/SMDiagnostic.h"+#include "LLVM/Internal/FFI/InlineAssembly.h"+#include "LLVM/Internal/FFI/Target.h"+#include "LLVM/Internal/FFI/CallingConvention.h"+#include "LLVM/Internal/FFI/GlobalValue.h"+#include "LLVM/Internal/FFI/Type.h"+#include "LLVM/Internal/FFI/Constant.h"+#include "LLVM/Internal/FFI/Analysis.h"+#include "LLVM/Internal/FFI/LibFunc.h"+#include "LLVM/Internal/FFI/OrcJIT.h"++import Language.Haskell.TH.Quote++import Data.Bits+import Foreign.C+import Foreign.Storable++#{+define hsc_inject(l, typ, cons, hprefix, recmac) { \+  struct { const char *s; unsigned n; } *p, list[] = { LLVM_HS_FOR_EACH_ ## l(recmac) }; \+  for(p = list; p < list + sizeof(list)/sizeof(list[0]); ++p) { \+    hsc_printf(#hprefix "%s :: " #typ "\n", p->s); \+    hsc_printf(#hprefix "%s = " #cons " %u\n", p->s, p->n); \+  } \+  hsc_printf(#hprefix "P :: QuasiQuoter\n" \+             #hprefix "P = QuasiQuoter {\n" \+             "  quoteExp = undefined,\n" \+             "  quotePat = \\s -> dataToPatQ (const Nothing) $ case s of"); \+  for(p = list; p < list + sizeof(list)/sizeof(list[0]); ++p) { \+    hsc_printf("\n    \"%s\" -> " #hprefix "%s", p->s, p->s); \+  } \+  hsc_printf("\n    x -> error $ \"bad quasiquoted FFI constant for " #hprefix ": \" ++ x"); \+  hsc_printf(",\n" \+             "  quoteType = undefined,\n" \+             "  quoteDec = undefined\n" \+             " }\n"); \+}+}++deriving instance Data CUInt++newtype LLVMBool = LLVMBool CUInt++newtype OwnerTransfered a = OwnerTransfered a+  deriving (Storable)++newtype NothingAsMinusOne h = NothingAsMinusOne CInt+  deriving (Storable)++newtype NothingAsEmptyString c = NothingAsEmptyString c+  deriving (Storable)++newtype CPPOpcode = CPPOpcode CUInt+  deriving (Eq, Ord, Show, Typeable, Data)++newtype ICmpPredicate = ICmpPredicate CUInt+  deriving (Eq, Ord, Show, Typeable, Data)+#{enum ICmpPredicate, ICmpPredicate,+ iCmpPredEQ = LLVMIntEQ,+ iCmpPredNE = LLVMIntNE,+ iCmpPredUGT = LLVMIntUGT,+ iCmpPredUGE = LLVMIntUGE,+ iCmpPredULT = LLVMIntULT,+ iCmpPredULE = LLVMIntULE,+ iCmpPredSGT = LLVMIntSGT,+ iCmpPredSGE = LLVMIntSGE,+ iCmpPredSLT = LLVMIntSLT,+ iCmpPredSLE = LLVMIntSLE+}++newtype FCmpPredicate = FCmpPredicate CUInt+  deriving (Eq, Ord, Show, Typeable, Data)+#{enum FCmpPredicate, FCmpPredicate,+ fCmpPredFalse = LLVMRealPredicateFalse,+ fCmpPredOEQ = LLVMRealOEQ,+ fCmpPredOGT = LLVMRealOGT,+ fCmpPredOGE = LLVMRealOGE,+ fCmpPredOLT = LLVMRealOLT,+ fCmpPredOLE = LLVMRealOLE,+ fCmpPredONE = LLVMRealONE,+ fCmpPredORD = LLVMRealORD,+ fCmpPredUNO = LLVMRealUNO,+ fCmpPredUEQ = LLVMRealUEQ,+ fCmpPredUGT = LLVMRealUGT,+ fCmpPredUGE = LLVMRealUGE,+ fCmpPredULT = LLVMRealULT,+ fCmpPredULE = LLVMRealULE,+ fCmpPredUNE = LLVMRealUNE,+ fcmpPredTrue = LLVMRealPredicateTrue+}++newtype MDKindID = MDKindID CUInt+  deriving (Storable)++newtype FastMathFlags = FastMathFlags CUInt+  deriving (Eq, Ord, Show, Typeable, Data, Num, Bits)+#define FMF_Rec(n,l) { #n, LLVM ## n, },+#{inject FAST_MATH_FLAG, FastMathFlags, FastMathFlags, fastMathFlags, FMF_Rec}++newtype MemoryOrdering = MemoryOrdering CUInt+  deriving (Eq, Typeable, Data)+#define MO_Rec(n) { #n, LLVMAtomicOrdering ## n },+#{inject ATOMIC_ORDERING, MemoryOrdering, MemoryOrdering, memoryOrdering, MO_Rec}++newtype UnnamedAddr = UnnamedAddr CUInt+  deriving (Eq, Typeable, Data)+#define UA_Rec(n) { #n, LLVMUnnamedAddr ## n },+#{inject UNNAMED_ADDR, UnnamedAddr, UnnamedAddr, unnamedAddr, UA_Rec}++newtype SynchronizationScope = SynchronizationScope CUInt+  deriving (Eq, Typeable, Data)+#define SS_Rec(n) { #n, LLVM ## n ## SynchronizationScope },+#{inject SYNCRONIZATION_SCOPE, SynchronizationScope, SynchronizationScope, synchronizationScope, SS_Rec}++newtype TailCallKind = TailCallKind CUInt+  deriving (Eq, Typeable, Data)+#define TCK_Rec(n) { #n, LLVM_Hs_TailCallKind_ ## n },+#{inject TAIL_CALL_KIND, TailCallKind, TailCallKind, tailCallKind, TCK_Rec}++newtype Linkage = Linkage CUInt+  deriving (Eq, Read, Show, Typeable, Data)+#define LK_Rec(n) { #n, LLVM ## n ## Linkage },+#{inject LINKAGE, Linkage, Linkage, linkage, LK_Rec}++newtype Visibility = Visibility CUInt+  deriving (Eq, Read, Show, Typeable, Data)+#define VIS_Rec(n) { #n, LLVM ## n ## Visibility },+#{inject VISIBILITY, Visibility, Visibility, visibility, VIS_Rec}++newtype COMDATSelectionKind = COMDATSelectionKind CUInt+  deriving (Eq, Read, Show, Typeable, Data)+#define CSK(n) { #n, LLVM_Hs_COMDAT_Selection_Kind_ ## n },+#{inject COMDAT_SELECTION_KIND, COMDATSelectionKind, COMDATSelectionKind, comdatSelectionKind, CSK}++newtype DLLStorageClass = DLLStorageClass CUInt+  deriving (Eq, Read, Show, Typeable, Data)+#define DLLSC_Rec(n) { #n, LLVM ## n ## StorageClass },+#{inject DLL_STORAGE_CLASS, DLLStorageClass, DLLStorageClass, dllStorageClass, DLLSC_Rec}++newtype CallingConvention = CallingConvention CUInt+  deriving (Eq, Read, Show, Typeable, Data)+#define CC_Rec(l, n) { #l, LLVM_Hs_CallingConvention_ ## l },+#{inject CALLING_CONVENTION, CallingConvention, CallingConvention, callingConvention, CC_Rec}++newtype ThreadLocalMode = ThreadLocalMode CUInt+  deriving (Eq, Read, Show, Typeable, Data)+#define TLS_Rec(n) { #n, LLVM ## n },+#{inject THREAD_LOCAL_MODE, ThreadLocalMode, ThreadLocalMode, threadLocalMode, TLS_Rec}++newtype ValueSubclassId = ValueSubclassId CUInt+  deriving (Eq, Read, Show, Typeable, Data)+#define VSID_Rec(n) { #n, LLVM ## n ## SubclassId },+#{inject VALUE_SUBCLASS, ValueSubclassId, ValueSubclassId, valueSubclassId, VSID_Rec}++newtype DiagnosticKind = DiagnosticKind CUInt+  deriving (Eq, Read, Show, Typeable, Data)+#define DK_Rec(n) { #n, LLVMDiagnosticKind ## n },+#{inject DIAGNOSTIC_KIND, DiagnosticKind, DiagnosticKind, diagnosticKind, DK_Rec}++newtype AsmDialect = AsmDialect CUInt+  deriving (Eq, Read, Show, Typeable, Data)+#define ASM_Rec(n) { #n, LLVMAsmDialect_ ## n },+#{inject ASM_DIALECT, AsmDialect, AsmDialect, asmDialect, ASM_Rec}++newtype RMWOperation = RMWOperation CUInt+  deriving (Eq, Read, Show, Typeable, Data)+#define RMWOp_Rec(n) { #n, LLVMAtomicRMWBinOp ## n },+#{inject RMW_OPERATION, RMWOperation, RMWOperation, rmwOperation, RMWOp_Rec}++newtype RelocModel = RelocModel CUInt+  deriving (Eq, Read, Show, Typeable, Data)+#define RM_Rec(n,m) { #n, LLVMReloc ## n },+#{inject RELOC_MODEL, RelocModel, RelocModel, relocModel, RM_Rec}++newtype CodeModel = CodeModel CUInt+  deriving (Eq, Read, Show, Typeable, Data)+#define CM_Rec(n) { #n, LLVMCodeModel ## n },+#{inject CODE_MODEL, CodeModel, CodeModel, codeModel, CM_Rec}++newtype CodeGenOptLevel = CodeGenOptLevel CUInt+  deriving (Eq, Read, Show, Typeable, Data)+#define CGOL_Rec(n) { #n, LLVMCodeGenLevel ## n },+#{inject CODE_GEN_OPT_LEVEL, CodeGenOptLevel, CodeGenOptLevel, codeGenOptLevel, CGOL_Rec}++newtype CodeGenFileType = CodeGenFileType CUInt+  deriving (Eq, Read, Show, Typeable, Data)+#define CGFT_Rec(n) { #n, LLVM ## n ## File },+#{inject CODE_GEN_FILE_TYPE, CodeGenFileType, CodeGenFileType, codeGenFileType, CGFT_Rec}++newtype FloatABIType = FloatABIType CUInt+  deriving (Eq, Read, Show, Typeable, Data)+#define FAT_Rec(n) { #n, LLVM_Hs_FloatABI_ ## n },+#{inject FLOAT_ABI, FloatABIType, FloatABIType, floatABI, FAT_Rec}++newtype FPOpFusionMode = FPOpFusionMode CUInt+  deriving (Eq, Read, Show, Typeable, Data)+#define FPOFM_Rec(n) { #n, LLVM_Hs_FPOpFusionMode_ ## n },+#{inject FP_OP_FUSION_MODE, FPOpFusionMode, FPOpFusionMode, fpOpFusionMode, FPOFM_Rec}++newtype TargetOptionFlag = TargetOptionFlag CUInt+  deriving (Eq, Read, Show, Typeable, Data)+#define TOF_Rec(n) { #n, LLVM_Hs_TargetOptionFlag_ ## n },+#{inject TARGET_OPTION_FLAG, TargetOptionFlag, TargetOptionFlag, targetOptionFlag, TOF_Rec}++newtype TypeKind = TypeKind CUInt+  deriving (Eq, Read, Show, Typeable, Data)+#define TK_Rec(n) { #n, LLVM ## n ## TypeKind },+#{inject TYPE_KIND, TypeKind, TypeKind, typeKind, TK_Rec}++#define COMMA ,+#define IF_T(z) z+#define IF_F(z)+#define IF2(x) IF_ ## x+#define IF(x) IF2(x)+#define OR_TT T+#define OR_TF T+#define OR_FT T+#define OR_FF F+#define OR(x,y) OR_ ## x ## y+newtype ParameterAttributeKind = ParameterAttributeKind CUInt+  deriving (Eq, Read, Show, Typeable, Data)+#define PAK_Rec(n,p,r,f) IF(OR(p,r))({ #n COMMA LLVM_Hs_AttributeKind_ ## n} COMMA)+#{inject ATTRIBUTE_KIND, ParameterAttributeKind, ParameterAttributeKind, parameterAttributeKind, PAK_Rec}++newtype FunctionAttributeKind = FunctionAttributeKind CUInt+  deriving (Eq, Read, Show, Typeable, Data)+#define FAK_Rec(n,p,r,f) IF(f)({ #n COMMA LLVM_Hs_AttributeKind_ ## n} COMMA)+#{inject ATTRIBUTE_KIND, FunctionAttributeKind, FunctionAttributeKind, functionAttributeKind, FAK_Rec}++newtype FloatSemantics = FloatSemantics CUInt+  deriving (Eq, Read, Show, Typeable, Data)+#define FS_Rec(n) { #n, LLVMFloatSemantics ## n },+#{inject FLOAT_SEMANTICS, FloatSemantics, FloatSemantics, floatSemantics, FS_Rec}++newtype VerifierFailureAction = VerifierFailureAction CUInt+  deriving (Eq, Read, Show, Bits, Typeable, Data, Num)+#define VFA_Rec(n) { #n, LLVM ## n ## Action },+#{inject VERIFIER_FAILURE_ACTION, VerifierFailureAction, VerifierFailureAction, verifierFailureAction, VFA_Rec}++newtype LibFunc = LibFunc CUInt+  deriving (Eq, Read, Show, Bits, Typeable, Data, Num, Storable)+#define LF_Rec(n) { #n, LLVMLibFunc__ ## n },+#{inject LIB_FUNC, LibFunc, LibFunc, libFunc__, LF_Rec}++newtype JITSymbolFlags = JITSymbolFlags CUInt+  deriving (Eq, Read, Show, Bits, Typeable, Data, Num, Storable)+#define SF_Rec(n) { #n, LLVMJITSymbolFlag ## n },+#{inject JIT_SYMBOL_FLAG, JITSymbolFlags, JITSymbolFlags, jitSymbolFlags, SF_Rec}
+ src/LLVM/Internal/FFI/LibFunc.h view
@@ -0,0 +1,332 @@+#ifndef __LLVM_INTERNAL_FFI__LIB_FUNC__H__+#define __LLVM_INTERNAL_FFI__LIB_FUNC__H__++#define LLVM_HS_FOR_EACH_LIB_FUNC(macro)		\+	macro(under_IO_getc)													\+	macro(under_IO_putc)													\+	macro(ZdaPv)																	\+	macro(ZdaPvRKSt9nothrow_t)										\+	macro(ZdlPv)																	\+	macro(ZdlPvRKSt9nothrow_t)										\+	macro(Znaj)																		\+	macro(ZnajRKSt9nothrow_t)											\+	macro(Znam)																		\+	macro(ZnamRKSt9nothrow_t)											\+	macro(Znwj)																		\+	macro(ZnwjRKSt9nothrow_t)											\+	macro(Znwm)																		\+	macro(ZnwmRKSt9nothrow_t)											\+	macro(cospi)																	\+	macro(cospif)																	\+	macro(cxa_atexit)															\+	macro(cxa_guard_abort)												\+	macro(cxa_guard_acquire)											\+	macro(cxa_guard_release)											\+	macro(dunder_isoc99_scanf)										\+	macro(dunder_isoc99_sscanf)										\+	macro(memcpy_chk)															\+	macro(sincospi_stret)													\+	macro(sincospif_stret)												\+	macro(sinpi)																	\+	macro(sinpif)																	\+	macro(sqrt_finite)														\+	macro(sqrtf_finite)														\+	macro(sqrtl_finite)														\+	macro(dunder_strdup)													\+	macro(dunder_strndup)													\+	macro(dunder_strtok_r)												\+	macro(abs)																		\+	macro(access)																	\+	macro(acos)																		\+	macro(acosf)																	\+	macro(acosh)																	\+	macro(acoshf)																	\+	macro(acoshl)																	\+	macro(acosl)																	\+	macro(asin)																		\+	macro(asinf)																	\+	macro(asinh)																	\+	macro(asinhf)																	\+	macro(asinhl)																	\+	macro(asinl)																	\+	macro(atan)																		\+	macro(atan2)																	\+	macro(atan2f)																	\+	macro(atan2l)																	\+	macro(atanf)																	\+	macro(atanh)																	\+	macro(atanhf)																	\+	macro(atanhl)																	\+	macro(atanl)																	\+	macro(atof)																		\+	macro(atoi)																		\+	macro(atol)																		\+	macro(atoll)																	\+	macro(bcmp)																		\+	macro(bcopy)																	\+	macro(bzero)																	\+	macro(calloc)																	\+	macro(cbrt)																		\+	macro(cbrtf)																	\+	macro(cbrtl)																	\+	macro(ceil)																		\+	macro(ceilf)																	\+	macro(ceill)																	\+	macro(chmod)																	\+	macro(chown)																	\+	macro(clearerr)																\+	macro(closedir)																\+	macro(copysign)																\+	macro(copysignf)															\+	macro(copysignl)															\+	macro(cos)																		\+	macro(cosf)																		\+	macro(cosh)																		\+	macro(coshf)																	\+	macro(coshl)																	\+	macro(cosl)																		\+	macro(ctermid)																\+	macro(exp)																		\+	macro(exp10)																	\+	macro(exp10f)																	\+	macro(exp10l)																	\+	macro(exp2)																		\+	macro(exp2f)																	\+	macro(exp2l)																	\+	macro(expf)																		\+	macro(expl)																		\+	macro(expm1)																	\+	macro(expm1f)																	\+	macro(expm1l)																	\+	macro(fabs)																		\+	macro(fabsf)																	\+	macro(fabsl)																	\+	macro(fclose)																	\+	macro(fdopen)																	\+	macro(feof)																		\+	macro(ferror)																	\+	macro(fflush)																	\+	macro(ffs)																		\+	macro(ffsl)																		\+	macro(ffsll)																	\+	macro(fgetc)																	\+	macro(fgetpos)																\+	macro(fgets)																	\+	macro(fileno)																	\+	macro(fiprintf)																\+	macro(flockfile)															\+	macro(floor)																	\+	macro(floorf)																	\+	macro(floorl)																	\+	macro(fmax)																		\+	macro(fmaxf)																	\+	macro(fmaxl)																	\+	macro(fmin)																		\+	macro(fminf)																	\+	macro(fminl)																	\+	macro(fmod)																		\+	macro(fmodf)																	\+	macro(fmodl)																	\+	macro(fopen)																	\+	macro(fopen64)																\+	macro(fprintf)																\+	macro(fputc)																	\+	macro(fputs)																	\+	macro(fread)																	\+	macro(free)																		\+	macro(frexp)																	\+	macro(frexpf)																	\+	macro(frexpl)																	\+	macro(fscanf)																	\+	macro(fseek)																	\+	macro(fseeko)																	\+	macro(fseeko64)																\+	macro(fsetpos)																\+	macro(fstat)																	\+	macro(fstat64)																\+	macro(fstatvfs)																\+	macro(fstatvfs64)															\+	macro(ftell)																	\+	macro(ftello)																	\+	macro(ftello64)																\+	macro(ftrylockfile)														\+	macro(funlockfile)														\+	macro(fwrite)																	\+	macro(getc)																		\+	macro(getc_unlocked)													\+	macro(getchar)																\+	macro(getenv)																	\+	macro(getitimer)															\+	macro(getlogin_r)															\+	macro(getpwnam)																\+	macro(gets)																		\+	macro(gettimeofday)														\+	macro(htonl)																	\+	macro(htons)																	\+	macro(iprintf)																\+	macro(isascii)																\+	macro(isdigit)																\+	macro(labs)																		\+	macro(lchown)																	\+	macro(ldexp)																	\+	macro(ldexpf)																	\+	macro(ldexpl)																	\+	macro(llabs)																	\+	macro(log)																		\+	macro(log10)																	\+	macro(log10f)																	\+	macro(log10l)																	\+	macro(log1p)																	\+	macro(log1pf)																	\+	macro(log1pl)																	\+	macro(log2)																		\+	macro(log2f)																	\+	macro(log2l)																	\+	macro(logb)																		\+	macro(logbf)																	\+	macro(logbl)																	\+	macro(logf)																		\+	macro(logl)																		\+	macro(lstat)																	\+	macro(lstat64)																\+	macro(malloc)																	\+	macro(memalign)																\+	macro(memccpy)																\+	macro(memchr)																	\+	macro(memcmp)																	\+	macro(memcpy)																	\+	macro(memmove)																\+	macro(memrchr)																\+	macro(memset)																	\+	macro(memset_pattern16)												\+	macro(mkdir)																	\+	macro(mktime)																	\+	macro(modf)																		\+	macro(modff)																	\+	macro(modfl)																	\+	macro(nearbyint)															\+	macro(nearbyintf)															\+	macro(nearbyintl)															\+	macro(ntohl)																	\+	macro(ntohs)																	\+	macro(open)																		\+	macro(open64)																	\+	macro(opendir)																\+	macro(pclose)																	\+	macro(perror)																	\+	macro(popen)																	\+	macro(posix_memalign)													\+	macro(pow)																		\+	macro(powf)																		\+	macro(powl)																		\+	macro(pread)																	\+	macro(printf)																	\+	macro(putc)																		\+	macro(putchar)																\+	macro(puts)																		\+	macro(pwrite)																	\+	macro(qsort)																	\+	macro(read)																		\+	macro(readlink)																\+	macro(realloc)																\+	macro(reallocf)																\+	macro(realpath)																\+	macro(remove)																	\+	macro(rename)																	\+	macro(rewind)																	\+	macro(rint)																		\+	macro(rintf)																	\+	macro(rintl)																	\+	macro(rmdir)																	\+	macro(round)																	\+	macro(roundf)																	\+	macro(roundl)																	\+	macro(scanf)																	\+	macro(setbuf)																	\+	macro(setitimer)															\+	macro(setvbuf)																\+	macro(sin)																		\+	macro(sinf)																		\+	macro(sinh)																		\+	macro(sinhf)																	\+	macro(sinhl)																	\+	macro(sinl)																		\+	macro(siprintf)																\+	macro(snprintf)																\+	macro(sprintf)																\+	macro(sqrt)																		\+	macro(sqrtf)																	\+	macro(sqrtl)																	\+	macro(sscanf)																	\+	macro(stat)																		\+	macro(stat64)																	\+	macro(statvfs)																\+	macro(statvfs64)															\+	macro(stpcpy)																	\+	macro(stpncpy)																\+	macro(strcasecmp)															\+	macro(strcat)																	\+	macro(strchr)																	\+	macro(strcmp)																	\+	macro(strcoll)																\+	macro(strcpy)																	\+	macro(strcspn)																\+	macro(strdup)																	\+	macro(strlen)																	\+	macro(strncasecmp)														\+	macro(strncat)																\+	macro(strncmp)																\+	macro(strncpy)																\+	macro(strndup)																\+	macro(strnlen)																\+	macro(strpbrk)																\+	macro(strrchr)																\+	macro(strspn)																	\+	macro(strstr)																	\+	macro(strtod)																	\+	macro(strtof)																	\+	macro(strtok)																	\+	macro(strtok_r)																\+	macro(strtol)																	\+	macro(strtold)																\+	macro(strtoll)																\+	macro(strtoul)																\+	macro(strtoull)																\+	macro(strxfrm)																\+	macro(system)																	\+	macro(tan)																		\+	macro(tanf)																		\+	macro(tanh)																		\+	macro(tanhf)																	\+	macro(tanhl)																	\+	macro(tanl)																		\+	macro(times)																	\+	macro(tmpfile)																\+	macro(tmpfile64)															\+	macro(toascii)																\+	macro(trunc)																	\+	macro(truncf)																	\+	macro(truncl)																	\+	macro(uname)																	\+	macro(ungetc)																	\+	macro(unlink)																	\+	macro(unsetenv)																\+	macro(utime)																	\+	macro(utimes)																	\+	macro(valloc)																	\+	macro(vfprintf)																\+	macro(vfscanf)																\+	macro(vprintf)																\+	macro(vscanf)																	\+	macro(vsnprintf)															\+	macro(vsprintf)																\+	macro(vsscanf)																\+	macro(write)++typedef enum {+#define ENUM_CASE(x) LLVMLibFunc__ ## x,+LLVM_HS_FOR_EACH_LIB_FUNC(ENUM_CASE)+#undef ENUM_CASE+} LLVMLibFunc;++#endif
+ src/LLVM/Internal/FFI/MemoryBuffer.hs view
@@ -0,0 +1,28 @@+{-# LANGUAGE+  ForeignFunctionInterface+  #-}+module LLVM.Internal.FFI.MemoryBuffer where++import LLVM.Prelude++import Foreign.Ptr+import Foreign.C++import LLVM.Internal.FFI.LLVMCTypes++data MemoryBuffer++foreign import ccall unsafe "LLVMCreateMemoryBufferWithContentsOfFile" createMemoryBufferWithContentsOfFile ::+  Ptr CChar -> Ptr (Ptr MemoryBuffer) -> Ptr (OwnerTransfered CString) -> IO LLVMBool++foreign import ccall unsafe "LLVMCreateMemoryBufferWithMemoryRange" createMemoryBufferWithMemoryRange ::+  Ptr CChar -> CSize -> CString -> LLVMBool -> IO (Ptr MemoryBuffer)++foreign import ccall unsafe "LLVMGetBufferStart" getBufferStart ::+  Ptr MemoryBuffer -> IO (Ptr CChar)++foreign import ccall unsafe "LLVMGetBufferSize" getBufferSize ::+  Ptr MemoryBuffer -> IO CSize++foreign import ccall unsafe "LLVMDisposeMemoryBuffer" disposeMemoryBuffer ::+  Ptr MemoryBuffer -> IO ()
+ src/LLVM/Internal/FFI/Metadata.hpp view
@@ -0,0 +1,11 @@+#include "llvm/IR/Metadata.h"+#include "llvm-c/Core.h"++namespace llvm {+typedef struct LLVMOpaqueMetadata *LLVMMetadataRef;+DEFINE_ISA_CONVERSION_FUNCTIONS(Metadata, LLVMMetadataRef)++inline Metadata **unwrap(LLVMMetadataRef *Vals) {+  return reinterpret_cast<Metadata**>(Vals);+}+}
+ src/LLVM/Internal/FFI/Metadata.hs view
@@ -0,0 +1,93 @@+{-#+  LANGUAGE+  ForeignFunctionInterface+  #-}++module LLVM.Internal.FFI.Metadata where++import LLVM.Prelude++import Foreign.Ptr+import Foreign.C++import LLVM.Internal.FFI.Context+import LLVM.Internal.FFI.PtrHierarchy+import LLVM.Internal.FFI.LLVMCTypes++foreign import ccall unsafe "LLVM_Hs_IsAMDString" isAMDString ::+  Ptr Metadata -> IO (Ptr MDString)++foreign import ccall unsafe "LLVM_Hs_IsAMDNode" isAMDNode ::+  Ptr Metadata -> IO (Ptr MDNode)++foreign import ccall unsafe "LLVM_Hs_IsAMDValue" isAMDValue ::+  Ptr Metadata -> IO (Ptr MDValue)++foreign import ccall unsafe "LLVM_Hs_IsAMetadataOperand" isAMetadataOperand ::+  Ptr Value -> IO (Ptr MetadataAsVal)++foreign import ccall unsafe "LLVM_Hs_GetMDValue" getMDValue ::+  Ptr MDValue -> IO (Ptr Value)++foreign import ccall unsafe "LLVM_Hs_GetMetadataOperand" getMetadataOperand ::+  Ptr MetadataAsVal -> IO (Ptr Metadata)++foreign import ccall unsafe "LLVMGetMDKindIDInContext" getMDKindIDInContext' ::+  Ptr Context -> Ptr CChar -> CUInt -> IO MDKindID++getMDKindIDInContext :: Ptr Context -> (Ptr CChar, CUInt) -> IO MDKindID+getMDKindIDInContext ctx (c, n) = getMDKindIDInContext' ctx c n++foreign import ccall unsafe "LLVM_Hs_GetMDKindNames" getMDKindNames ::+  Ptr Context -> Ptr (Ptr CChar) -> Ptr CUInt -> CUInt -> IO CUInt++foreign import ccall unsafe "LLVM_Hs_MDStringInContext" mdStringInContext' ::+  Ptr Context -> CString -> CUInt -> IO (Ptr MDString)++foreign import ccall unsafe "LLVM_Hs_MDValue" mdValue ::+  Ptr Value -> IO (Ptr MDValue)++foreign import ccall unsafe "LLVM_Hs_MetadataOperand" metadataOperand ::+  Ptr Context -> Ptr Metadata -> IO (Ptr Value)++mdStringInContext :: Ptr Context -> (CString, CUInt) -> IO (Ptr MDString)+mdStringInContext ctx (p, n) = mdStringInContext' ctx p n++foreign import ccall unsafe "LLVM_Hs_GetMDString" getMDString ::+  Ptr MDString -> Ptr CUInt -> IO CString++foreign import ccall unsafe "LLVM_Hs_MDNodeInContext" createMDNodeInContext' ::+  Ptr Context -> Ptr (Ptr Metadata) -> CUInt -> IO (Ptr MDNode)++createMDNodeInContext :: Ptr Context -> (CUInt, Ptr (Ptr Metadata)) -> IO (Ptr MDNode)+createMDNodeInContext ctx (n, vs) = createMDNodeInContext' ctx vs n++foreign import ccall unsafe "LLVM_Hs_CreateTemporaryMDNodeInContext" createTemporaryMDNodeInContext ::+  Ptr Context -> IO (Ptr MDNode)++foreign import ccall unsafe "LLVM_Hs_DestroyTemporaryMDNode" destroyTemporaryMDNode ::+  Ptr MDNode -> IO ()++foreign import ccall unsafe "LLVM_Hs_GetMDNodeNumOperands" getMDNodeNumOperands ::+  Ptr MDNode -> IO CUInt++foreign import ccall unsafe "LLVM_Hs_GetMDNodeOperands" getMDNodeOperands ::+  Ptr MDNode -> Ptr (Ptr Metadata) -> IO ()++foreign import ccall unsafe "LLVM_Hs_GetNamedMetadataName" getNamedMetadataName ::+  Ptr NamedMetadata -> Ptr CUInt -> IO (Ptr CChar)++foreign import ccall unsafe "LLVM_Hs_GetNamedMetadataNumOperands" getNamedMetadataNumOperands ::+  Ptr NamedMetadata -> IO CUInt++foreign import ccall unsafe "LLVM_Hs_GetNamedMetadataOperands" getNamedMetadataOperands ::+  Ptr NamedMetadata -> Ptr (Ptr MDNode) -> IO ()++foreign import ccall unsafe "LLVM_Hs_NamedMetadataAddOperands" namedMetadataAddOperands' ::+  Ptr NamedMetadata -> Ptr (Ptr MDNode) -> CUInt -> IO ()++foreign import ccall unsafe "LLVM_Hs_MetadataReplaceAllUsesWith" metadataReplaceAllUsesWith ::+  Ptr MDNode -> Ptr Metadata -> IO ()++namedMetadataAddOperands :: Ptr NamedMetadata -> (CUInt, Ptr (Ptr MDNode)) -> IO ()+namedMetadataAddOperands nm (n, vs) = namedMetadataAddOperands' nm vs n
+ src/LLVM/Internal/FFI/MetadataC.cpp view
@@ -0,0 +1,151 @@+#define __STDC_LIMIT_MACROS++#include <iostream>+#include "LLVM/Internal/FFI/Metadata.hpp"+#include "llvm/Support/FormattedStream.h"++#include "llvm/Config/llvm-config.h"+#include "llvm/IR/LLVMContext.h"+#include "llvm/IR/Metadata.h"+#include "llvm-c/Core.h"++using namespace llvm;++extern "C" {++LLVMMetadataRef LLVM_Hs_IsAMDString(LLVMMetadataRef md) {+    if (isa<MDString>(unwrap(md))) {+        return md;+    }+    return nullptr;+}++LLVMMetadataRef LLVM_Hs_MDStringInContext(LLVMContextRef c,+                                               const char *str, unsigned slen) {+    return wrap(MDString::get(*unwrap(c), StringRef(str, slen)));+}++const char *LLVM_Hs_GetMDString(LLVMMetadataRef md, unsigned* len) {+    if (const MDString *S = dyn_cast<MDString>(unwrap(md))) {+      *len = S->getString().size();+      return S->getString().data();+    }+    *len = 0;+    return nullptr;+}++LLVMMetadataRef LLVM_Hs_MDValue(LLVMValueRef v) {+    return wrap(ValueAsMetadata::get(unwrap(v)));+}++LLVMValueRef LLVM_Hs_MetadataOperand(LLVMContextRef c, LLVMMetadataRef md) {+    return wrap(MetadataAsValue::get(*unwrap(c), unwrap(md)));+}++LLVMMetadataRef LLVM_Hs_IsAMDNode(LLVMMetadataRef md) {+    if (isa<MDNode>(unwrap(md))) {+        return md;+    }+    return nullptr;+}++LLVMValueRef LLVM_Hs_GetMDValue(LLVMMetadataRef md) {+    return wrap(unwrap<ValueAsMetadata>(md)->getValue());+}++LLVMMetadataRef LLVM_Hs_GetMetadataOperand(LLVMValueRef val) {+    return wrap(unwrap<MetadataAsValue>(val)->getMetadata());+}++LLVMMetadataRef LLVM_Hs_MDNodeInContext(LLVMContextRef c,+                                             LLVMMetadataRef *mds,+                                             unsigned count) {+    return wrap(MDNode::get(*unwrap(c), ArrayRef<Metadata *>(unwrap(mds), count)));+}++LLVMMetadataRef LLVM_Hs_IsAMDValue(LLVMMetadataRef md) {+    if (isa<ValueAsMetadata>(unwrap(md))) {+        return md;+    }+    return nullptr;+}+++LLVMValueRef LLVM_Hs_IsAMetadataOperand(LLVMValueRef val) {+    if (isa<MetadataAsValue>(unwrap(val))) {+        return val;+    }+    return nullptr;+}+++unsigned LLVM_Hs_GetMDKindNames(+	LLVMContextRef c,+	const char **s,+	unsigned *l,+	unsigned n+) {+	SmallVector<StringRef, 8> ns;+	unwrap(c)->getMDKindNames(ns);+	if (ns.size() <= n) {+		for(unsigned i=0; i < ns.size(); ++i) {+			s[i] = ns[i].data();+			l[i] = ns[i].size();+		}+	}+	return ns.size();+}++unsigned LLVM_Hs_GetMDNodeNumOperands(LLVMMetadataRef v) {+	return unwrap<MDNode>(v)->getNumOperands();+}++void LLVM_Hs_NamedMetadataAddOperands(+	NamedMDNode *n,+	LLVMMetadataRef *ops,+	unsigned nOps+) {+	for(unsigned i = 0; i != nOps; ++i) n->addOperand(unwrap<MDNode>(ops[i]));+}++const char *LLVM_Hs_GetNamedMetadataName(+	NamedMDNode *n,+	unsigned *len+) {+	StringRef s = n->getName();+	*len = s.size();+	return s.data();+}++unsigned LLVM_Hs_GetNamedMetadataNumOperands(NamedMDNode *n) {+	return n->getNumOperands();+}++void LLVM_Hs_GetNamedMetadataOperands(NamedMDNode *n, LLVMMetadataRef *dest) {+	for(unsigned i = 0; i != n->getNumOperands(); ++i)+		dest[i] = wrap(n->getOperand(i));+}++LLVMMetadataRef LLVM_Hs_CreateTemporaryMDNodeInContext(LLVMContextRef c) {+	return wrap(MDNode::getTemporary(*unwrap(c), ArrayRef<Metadata *>()).release());+}++void LLVM_Hs_DestroyTemporaryMDNode(LLVMMetadataRef v) {+    MDNode::deleteTemporary(unwrap<MDNode>(v));+}++void LLVM_Hs_GetMDNodeOperands(LLVMMetadataRef md, LLVMMetadataRef *dest) {+    const auto *N = cast<MDNode>(unwrap(md));+    const unsigned numOperands = N->getNumOperands();+    for (unsigned i = 0; i < numOperands; i++)+        dest[i] = wrap(N->getOperand(i));+}++void LLVM_Hs_MetadataReplaceAllUsesWith(LLVMMetadataRef md, LLVMMetadataRef replacement) {+    auto *Node = unwrap<MDNode>(md);+    Node->replaceAllUsesWith(unwrap<Metadata>(replacement));+    MDNode::deleteTemporary(Node);+}++}+
+ src/LLVM/Internal/FFI/Module.hs view
@@ -0,0 +1,103 @@+{-# LANGUAGE+  ForeignFunctionInterface+  #-}+module LLVM.Internal.FFI.Module where++import LLVM.Prelude++import Foreign.Ptr+import Foreign.C++import LLVM.Internal.FFI.Context+import LLVM.Internal.FFI.GlobalValue (COMDAT)+import LLVM.Internal.FFI.LLVMCTypes+import LLVM.Internal.FFI.PtrHierarchy+import LLVM.Internal.FFI.Type++data Module++foreign import ccall unsafe "LLVMModuleCreateWithNameInContext" moduleCreateWithNameInContext ::+  CString -> Ptr Context -> IO (Ptr Module)++foreign import ccall unsafe "LLVMGetModuleContext" getModuleContext ::+  Ptr Module -> IO (Ptr Context)++foreign import ccall unsafe "LLVMDisposeModule" disposeModule ::+  Ptr Module -> IO ()++foreign import ccall unsafe "LLVMGetDataLayout" getDataLayout ::+  Ptr Module -> IO CString++foreign import ccall unsafe "LLVMSetDataLayout" setDataLayout ::+  Ptr Module -> CString -> IO ()++foreign import ccall unsafe "LLVMGetTarget" getTargetTriple ::+  Ptr Module -> IO CString++foreign import ccall unsafe "LLVMSetTarget" setTargetTriple ::+  Ptr Module -> CString -> IO ()++foreign import ccall unsafe "LLVM_Hs_GetModuleIdentifier" getModuleIdentifier ::+  Ptr Module -> IO (OwnerTransfered CString)++foreign import ccall unsafe "LLVM_Hs_GetSourceFileName" getSourceFileName ::+  Ptr Module -> IO (OwnerTransfered CString)++foreign import ccall unsafe "LLVM_Hs_SetSourceFileName" setSourceFileName ::+  Ptr Module -> Ptr CChar -> IO ()++foreign import ccall unsafe "LLVMGetFirstGlobal" getFirstGlobal ::+  Ptr Module -> IO (Ptr GlobalVariable)++foreign import ccall unsafe "LLVMGetNextGlobal" getNextGlobal ::+  Ptr GlobalVariable -> IO (Ptr GlobalVariable)++foreign import ccall unsafe "LLVM_Hs_GetFirstAlias" getFirstAlias ::+  Ptr Module -> IO (Ptr GlobalAlias)++foreign import ccall unsafe "LLVM_Hs_GetNextAlias" getNextAlias ::+  Ptr GlobalAlias -> IO (Ptr GlobalAlias)++foreign import ccall unsafe "LLVM_Hs_GetOrInsertCOMDAT" getOrInsertCOMDAT ::+  Ptr Module -> CString -> IO (Ptr COMDAT)++foreign import ccall unsafe "LLVMGetFirstFunction" getFirstFunction ::+  Ptr Module -> IO (Ptr Function)++foreign import ccall unsafe "LLVMGetNextFunction" getNextFunction ::+  Ptr Function -> IO (Ptr Function)++foreign import ccall unsafe "LLVM_Hs_GetFirstNamedMetadata" getFirstNamedMetadata ::+  Ptr Module -> IO (Ptr NamedMetadata)++foreign import ccall unsafe "LLVM_Hs_GetNextNamedMetadata" getNextNamedMetadata ::+  Ptr NamedMetadata -> IO (Ptr NamedMetadata)++foreign import ccall unsafe "LLVMAddGlobalInAddressSpace" addGlobalInAddressSpace ::+  Ptr Module -> Ptr Type -> CString -> CUInt -> IO (Ptr GlobalVariable)++foreign import ccall unsafe "LLVM_Hs_JustAddAlias" justAddAlias ::+  Ptr Module -> Ptr Type -> AddrSpace -> CString -> IO (Ptr GlobalAlias)++foreign import ccall unsafe "LLVMAddFunction" addFunction ::+  Ptr Module -> CString -> Ptr Type -> IO (Ptr Function)++foreign import ccall unsafe "LLVMGetNamedFunction" getNamedFunction ::+  Ptr Module -> CString -> IO (Ptr Function)++foreign import ccall unsafe "LLVM_Hs_GetOrAddNamedMetadata" getOrAddNamedMetadata ::+  Ptr Module -> CString -> IO (Ptr NamedMetadata)++foreign import ccall unsafe "LLVM_Hs_ModuleAppendInlineAsm" moduleAppendInlineAsm' ::+  Ptr Module -> Ptr CChar -> CUInt -> IO ()++newtype ModuleAsm a = ModuleAsm a++moduleAppendInlineAsm :: Ptr Module -> ModuleAsm (Ptr CChar, CUInt) -> IO ()+moduleAppendInlineAsm m (ModuleAsm (c, n)) = moduleAppendInlineAsm' m c n++foreign import ccall unsafe "LLVM_Hs_ModuleGetInlineAsm" moduleGetInlineAsm ::+  Ptr Module -> IO (ModuleAsm CString)++foreign import ccall unsafe "LLVMLinkModules2" linkModules ::+  Ptr Module -> Ptr Module -> IO LLVMBool
+ src/LLVM/Internal/FFI/ModuleC.cpp view
@@ -0,0 +1,70 @@+#define __STDC_LIMIT_MACROS+#include "llvm/IR/Module.h"+#include "llvm-c/Core.h"++using namespace llvm;++extern "C" {++char *LLVM_Hs_GetModuleIdentifier(LLVMModuleRef val) {+	return strdup(unwrap(val)->getModuleIdentifier().c_str());+}++char *LLVM_Hs_GetSourceFileName(LLVMModuleRef val) {+	return strdup(unwrap(val)->getSourceFileName().c_str());+}++void LLVM_Hs_SetSourceFileName(LLVMModuleRef val, const char* sourceFileName) {+	return unwrap(val)->setSourceFileName(sourceFileName);+}++LLVMValueRef LLVM_Hs_GetFirstAlias(LLVMModuleRef m) {+	Module *mod = unwrap(m);+	Module::alias_iterator i = mod->alias_begin();+    if (i == mod->alias_end()) {+        return 0;+    }+    return wrap(&*i);+}++LLVMValueRef LLVM_Hs_GetNextAlias(LLVMValueRef a) {+	GlobalAlias *alias = unwrap<GlobalAlias>(a);+	Module::alias_iterator i(alias);+	if (++i == alias->getParent()->alias_end()) return 0;+	return wrap(&*i);+}++Comdat *LLVM_Hs_GetOrInsertCOMDAT(LLVMModuleRef m, const char *name) {+  return unwrap(m)->getOrInsertComdat(name);+}++// TODO (cocreature): Figure out if we can just change the linkage here+LLVMValueRef LLVM_Hs_JustAddAlias(LLVMModuleRef m, LLVMTypeRef ty, unsigned addrspace, const char *name) {+	return wrap(GlobalAlias::create(unwrap(ty), addrspace, GlobalValue::ExternalLinkage, name, 0, unwrap(m)));+}++NamedMDNode *LLVM_Hs_GetOrAddNamedMetadata(LLVMModuleRef m, const char *name) {+	return unwrap(m)->getOrInsertNamedMetadata(name);+}++NamedMDNode *LLVM_Hs_GetFirstNamedMetadata(LLVMModuleRef m) {+	Module *mod = unwrap(m);+	Module::named_metadata_iterator i = mod->named_metadata_begin();+	return i == mod->named_metadata_end() ? 0 : &*i;+}++NamedMDNode *LLVM_Hs_GetNextNamedMetadata(NamedMDNode *a) {+	Module::named_metadata_iterator i(a);+	if (++i == a->getParent()->named_metadata_end()) return 0;+	return &*i;+}++void LLVM_Hs_ModuleAppendInlineAsm(LLVMModuleRef m, const char *s, unsigned l) {+	unwrap(m)->appendModuleInlineAsm(StringRef(s,l));+}++const char *LLVM_Hs_ModuleGetInlineAsm(LLVMModuleRef m) {+	return unwrap(m)->getModuleInlineAsm().c_str();+}++}
+ src/LLVM/Internal/FFI/OrcJIT.h view
@@ -0,0 +1,15 @@+#ifndef __LLVM_INTERNAL_FFI__ORC_JIT__H__+#define __LLVM_INTERNAL_FFI__ORC_JIT__H__++#define LLVM_HS_FOR_EACH_JIT_SYMBOL_FLAG(macro) \+	macro(None)                                      \+	macro(Weak)                                      \+	macro(Exported)                                  \++typedef enum {+#define ENUM_CASE(x) LLVMJITSymbolFlag ## x,+LLVM_HS_FOR_EACH_JIT_SYMBOL_FLAG(ENUM_CASE)+#undef ENUM_CASE+} LLVMJITSymbolFlags;++#endif
+ src/LLVM/Internal/FFI/OrcJIT.hs view
@@ -0,0 +1,51 @@+{-# LANGUAGE ForeignFunctionInterface #-}++module LLVM.Internal.FFI.OrcJIT where++import LLVM.Prelude++import Foreign.C+import Foreign.Ptr++import LLVM.Internal.FFI.DataLayout+import LLVM.Internal.FFI.LLVMCTypes++data JITSymbol+data LambdaResolver+data ObjectLinkingLayer++newtype TargetAddress = TargetAddress Word64++type SymbolResolverFn = CString -> Ptr JITSymbol -> IO ()++foreign import ccall "wrapper" wrapSymbolResolverFn ::+  SymbolResolverFn -> IO (FunPtr SymbolResolverFn)++foreign import ccall safe "LLVM_Hs_disposeJITSymbol" disposeSymbol ::+  Ptr JITSymbol -> IO ()++foreign import ccall safe "LLVM_Hs_createLambdaResolver" createLambdaResolver ::+  FunPtr SymbolResolverFn ->+  FunPtr SymbolResolverFn ->+  IO (Ptr LambdaResolver)++foreign import ccall safe "LLVM_Hs_createObjectLinkingLayer" createObjectLinkingLayer ::+  IO (Ptr ObjectLinkingLayer)++foreign import ccall safe "LLVM_Hs_disposeObjectLinkingLayer" disposeObjectLinkingLayer ::+  Ptr ObjectLinkingLayer -> IO ()++foreign import ccall safe "LLVM_Hs_JITSymbol_getAddress" getAddress ::+  Ptr JITSymbol -> IO TargetAddress++foreign import ccall safe "LLVM_Hs_JITSymbol_getFlags" getFlags ::+  Ptr JITSymbol -> IO JITSymbolFlags++foreign import ccall safe "LLVM_Hs_setJITSymbol" setJITSymbol ::+  Ptr JITSymbol -> TargetAddress -> JITSymbolFlags -> IO ()++foreign import ccall safe "LLVM_Hs_getMangledSymbol" getMangledSymbol ::+  Ptr CString -> CString -> Ptr DataLayout -> IO ()++foreign import ccall safe "LLVM_Hs_disposeMangledSymbol" disposeMangledSymbol ::+  CString -> IO ()
+ src/LLVM/Internal/FFI/OrcJIT/CompileOnDemandLayer.hs view
@@ -0,0 +1,74 @@+{-# LANGUAGE ForeignFunctionInterface #-}+module LLVM.Internal.FFI.OrcJIT.CompileOnDemandLayer where++import LLVM.Prelude++import Foreign.C+import Foreign.Ptr++import LLVM.Internal.FFI.DataLayout+import LLVM.Internal.FFI.LLVMCTypes+import LLVM.Internal.FFI.Module+import LLVM.Internal.FFI.OrcJIT+import LLVM.Internal.FFI.OrcJIT.IRCompileLayer (IRCompileLayer)+import LLVM.Internal.FFI.PtrHierarchy++data IndirectStubsManagerBuilder+data JITCompileCallbackManager+data CompileOnDemandLayer+data Set a+data ModuleSetHandle++type PartitioningFn = Ptr Function -> Ptr (Set (Ptr Function)) -> IO ()++foreign import ccall "wrapper" wrapPartitioningFn ::+  PartitioningFn -> IO (FunPtr PartitioningFn)++foreign import ccall "wrapper" wrapErrorHandler ::+  IO () -> IO (FunPtr (IO ()))++foreign import ccall safe "LLVM_Hs_createLocalCompileCallbackManager" createLocalCompileCallbackManager ::+  CString -> TargetAddress -> IO (Ptr JITCompileCallbackManager)++foreign import ccall safe "LLVM_Hs_disposeCallbackManager" disposeCallbackManager ::+  Ptr JITCompileCallbackManager -> IO ()++foreign import ccall safe "LLVM_Hs_createLocalIndirectStubsManagerBuilder" createLocalIndirectStubsManagerBuilder ::+  CString -> IO (Ptr IndirectStubsManagerBuilder)++foreign import ccall safe "LLVM_Hs_disposeIndirectStubsManagerBuilder" disposeIndirectStubsManagerBuilder ::+  Ptr IndirectStubsManagerBuilder -> IO ()++foreign import ccall safe "LLVM_Hs_insertFun" insertFun ::+  Ptr (Set (Ptr Function)) -> Ptr Function -> IO ()++foreign import ccall safe "LLVM_Hs_createCompileOnDemandLayer" createCompileOnDemandLayer ::+  Ptr IRCompileLayer ->+  FunPtr PartitioningFn ->+  Ptr JITCompileCallbackManager ->+  Ptr IndirectStubsManagerBuilder ->+  LLVMBool ->+  IO (Ptr CompileOnDemandLayer)++foreign import ccall safe "LLVM_Hs_disposeCompileOnDemandLayer" disposeCompileOnDemandLayer ::+  Ptr CompileOnDemandLayer ->+  IO ()++foreign import ccall safe "LLVM_Hs_CompileOnDemandLayer_addModuleSet" addModuleSet ::+  Ptr CompileOnDemandLayer ->+  Ptr DataLayout ->+  Ptr (Ptr Module) ->+  CUInt ->+  Ptr LambdaResolver ->+  IO (Ptr ModuleSetHandle)++foreign import ccall safe "LLVM_Hs_CompileOnDemandLayer_removeModuleSet" removeModuleSet ::+  Ptr CompileOnDemandLayer ->+  Ptr ModuleSetHandle ->+  IO ()++foreign import ccall safe "LLVM_Hs_CompileOnDemandLayer_findSymbol" findSymbol ::+  Ptr CompileOnDemandLayer ->+  CString ->+  LLVMBool ->+  IO (Ptr JITSymbol)
+ src/LLVM/Internal/FFI/OrcJIT/IRCompileLayer.hs view
@@ -0,0 +1,36 @@+{-# LANGUAGE ForeignFunctionInterface #-}+module LLVM.Internal.FFI.OrcJIT.IRCompileLayer where++import LLVM.Prelude++import LLVM.Internal.FFI.DataLayout+import LLVM.Internal.FFI.LLVMCTypes+import LLVM.Internal.FFI.Module+import LLVM.Internal.FFI.OrcJIT+import LLVM.Internal.FFI.Target++import Foreign.Ptr+import Foreign.C++data IRCompileLayer+data ModuleSetHandle++foreign import ccall safe "LLVM_Hs_createIRCompileLayer" createIRCompileLayer ::+  Ptr ObjectLinkingLayer -> Ptr TargetMachine -> IO (Ptr IRCompileLayer)++foreign import ccall safe "LLVM_Hs_disposeIRCompileLayer" disposeIRCompileLayer ::+  Ptr IRCompileLayer -> IO ()++foreign import ccall safe "LLVM_Hs_IRCompileLayer_addModuleSet" addModuleSet ::+  Ptr IRCompileLayer ->+  Ptr DataLayout ->+  Ptr (Ptr Module) ->+  CUInt ->+  Ptr LambdaResolver ->+  IO (Ptr ModuleSetHandle)++foreign import ccall safe "LLVM_Hs_IRCompileLayer_removeModuleSet" removeModuleSet ::+  Ptr IRCompileLayer -> Ptr ModuleSetHandle -> IO ()++foreign import ccall safe "LLVM_Hs_IRCompileLayer_findSymbol" findSymbol ::+  Ptr IRCompileLayer -> CString -> LLVMBool -> IO (Ptr JITSymbol)
+ src/LLVM/Internal/FFI/OrcJITC.cpp view
@@ -0,0 +1,256 @@+#include "LLVM/Internal/FFI/OrcJIT.h"+#include "LLVM/Internal/FFI/Target.hpp"+#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"+#include "llvm/ExecutionEngine/Orc/CompileUtils.h"+#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"+#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"+#include "llvm/ExecutionEngine/JITSymbol.h"+#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"+#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"+#include "llvm/IR/Mangler.h"++#include <type_traits>++using namespace llvm;+using namespace orc;++typedef llvm::orc::ObjectLinkingLayer<> *LLVMObjectLinkingLayerRef;+typedef llvm::orc::IRCompileLayer<llvm::orc::ObjectLinkingLayer<>>+    LLVMIRCompileLayer;+typedef LLVMIRCompileLayer *LLVMIRCompileLayerRef;+typedef llvm::orc::CompileOnDemandLayer<LLVMIRCompileLayer>+    LLVMCompileOnDemandLayer;+typedef LLVMCompileOnDemandLayer *LLVMCompileOnDemandLayerRef;+typedef llvm::orc::JITCompileCallbackManager *LLVMJITCompileCallbackManagerRef;+typedef llvm::JITSymbol *LLVMJITSymbolRef;+typedef LLVMIRCompileLayer::ModuleSetHandleT *LLVMModuleSetHandleRef;+typedef LLVMCompileOnDemandLayer::ModuleSetHandleT *LLVMCODModuleSetHandleRef;+typedef llvm::orc::LambdaResolver<+    std::function<JITSymbol(const std::string &name)>,+    std::function<JITSymbol(const std::string &name)>>+    LLVMLambdaResolver;+typedef LLVMLambdaResolver *LLVMLambdaResolverRef;+typedef llvm::orc::IndirectStubsManager *LLVMIndirectStubsManagerRef;+typedef std::function<std::unique_ptr<llvm::orc::IndirectStubsManager>()>+    *LLVMIndirectStubsManagerBuilderRef;++static std::string mangle(StringRef name, LLVMTargetDataRef dataLayout) {+    std::string mangledName;+    {+        raw_string_ostream mangledNameStream(mangledName);+        Mangler::getNameWithPrefix(mangledNameStream, name,+                                   *unwrap(dataLayout));+    }+    return mangledName;+}++static std::vector<Module *> getModules(LLVMModuleRef *modules,+                                        unsigned moduleCount,+                                        LLVMTargetDataRef dataLayout) {+    std::vector<Module *> moduleVec(moduleCount);+    for (unsigned i = 0; i < moduleCount; ++i) {+        moduleVec.at(i) = unwrap(modules[i]);+        if (moduleVec.at(i)->getDataLayout().isDefault()) {+            moduleVec.at(i)->setDataLayout(*unwrap(dataLayout));+        }+    }+    return moduleVec;+}++extern "C" {+LLVMIRCompileLayerRef+LLVM_Hs_createIRCompileLayer(LLVMObjectLinkingLayerRef objectLayer,+                                  LLVMTargetMachineRef tm) {+    TargetMachine *tmm = unwrap(tm);+    return new IRCompileLayer<ObjectLinkingLayer<>>(*objectLayer,+                                                    SimpleCompiler(*tmm));+}++void LLVM_Hs_disposeIRCompileLayer(LLVMIRCompileLayerRef compileLayer) {+    delete compileLayer;+}++LLVMJITSymbolRef+LLVM_Hs_IRCompileLayer_findSymbol(LLVMIRCompileLayerRef compileLayer,+                                       const char *name,+                                       LLVMBool exportedSymbolsOnly) {+    JITSymbol symbol = compileLayer->findSymbol(name, exportedSymbolsOnly);+    return new JITSymbol(symbol);+}++void LLVM_Hs_disposeJITSymbol(LLVMJITSymbolRef symbol) { delete symbol; }++LLVMLambdaResolverRef LLVM_Hs_createLambdaResolver(+    void (*dylibResolver)(const char *, LLVMJITSymbolRef),+    void (*externalResolver)(const char *, LLVMJITSymbolRef)) {+    std::function<JITSymbol(const std::string &name)>+        dylibResolverFun = [dylibResolver](+            const std::string &name) -> JITSymbol {+        JITSymbol symbol(nullptr);+        dylibResolver(name.c_str(), &symbol);+        return symbol;+    };+    std::function<JITSymbol(const std::string &name)>+        externalResolverFun = [externalResolver](+            const std::string &name) -> JITSymbol {+        JITSymbol symbol(nullptr);+        externalResolver(name.c_str(), &symbol);+        return symbol;+    };+    auto lambdaResolver =+        createLambdaResolver(dylibResolverFun, externalResolverFun);+    return lambdaResolver.release();+}++LLVMModuleSetHandleRef LLVM_Hs_IRCompileLayer_addModuleSet(+    LLVMIRCompileLayerRef compileLayer, LLVMTargetDataRef dataLayout,+    LLVMModuleRef *modules, unsigned moduleCount,+    LLVMLambdaResolverRef resolver) {+    std::vector<Module *> moduleVec =+        getModules(modules, moduleCount, dataLayout);+    return new IRCompileLayer<ObjectLinkingLayer<>>::ModuleSetHandleT(+        compileLayer->addModuleSet(+            moduleVec, make_unique<SectionMemoryManager>(), resolver));+}++void LLVM_Hs_IRCompileLayer_removeModuleSet(+    LLVMIRCompileLayerRef compileLayer,+    LLVMModuleSetHandleRef moduleSetHandle) {+    compileLayer->removeModuleSet(*moduleSetHandle);+    delete moduleSetHandle;+}++LLVMObjectLinkingLayerRef LLVM_Hs_createObjectLinkingLayer() {+    return new ObjectLinkingLayer<>();+}++void LLVM_Hs_disposeObjectLinkingLayer(+    LLVMObjectLinkingLayerRef objectLayer) {+    delete objectLayer;+}++static JITSymbolFlags unwrap(LLVMJITSymbolFlags f) {+    JITSymbolFlags flags = JITSymbolFlags::None;+#define ENUM_CASE(x)                                                           \+    if (f & LLVMJITSymbolFlag##x)                                              \+        flags |= JITSymbolFlags::x;+    LLVM_HS_FOR_EACH_JIT_SYMBOL_FLAG(ENUM_CASE)+#undef ENUM_CASE+    return flags;+}++static LLVMJITSymbolFlags wrap(JITSymbolFlags f) {+    unsigned r = 0;+#define ENUM_CASE(x)                                                           \+    if ((char)(f & JITSymbolFlags::x))                                         \+        r |= (unsigned)LLVMJITSymbolFlag##x;+    LLVM_HS_FOR_EACH_JIT_SYMBOL_FLAG(ENUM_CASE)+#undef ENUM_CASE+    return LLVMJITSymbolFlags(r);+}++JITTargetAddress+LLVM_Hs_JITSymbol_getAddress(LLVMJITSymbolRef symbol) {+    return symbol->getAddress();+}++LLVMJITSymbolFlags LLVM_Hs_JITSymbol_getFlags(LLVMJITSymbolRef symbol) {+    return wrap(symbol->getFlags());+}++void LLVM_Hs_setJITSymbol(LLVMJITSymbolRef symbol,+                               JITTargetAddress addr,+                               LLVMJITSymbolFlags flags) {+    *symbol = JITSymbol(addr, unwrap(flags));+}++void LLVM_Hs_getMangledSymbol(char **mangledSymbol, const char *symbol,+                                   LLVMTargetDataRef dataLayout) {+    std::string mangled = mangle(symbol, dataLayout);+    *mangledSymbol = new char[mangled.size() + 1];+    strcpy(*mangledSymbol, mangled.c_str());+}++void LLVM_Hs_disposeMangledSymbol(char *mangledSymbol) {+    delete[] mangledSymbol;+}++LLVMJITCompileCallbackManagerRef LLVM_Hs_createLocalCompileCallbackManager(+    const char *triple, JITTargetAddress errorHandler) {+    return llvm::orc::createLocalCompileCallbackManager(Triple(triple),+                                                        errorHandler)+        .release();+}++void LLVM_Hs_disposeCallbackManager(+    LLVMJITCompileCallbackManagerRef callbackManager) {+    delete callbackManager;+}++LLVMIndirectStubsManagerBuilderRef+LLVM_Hs_createLocalIndirectStubsManagerBuilder(const char *triple) {+    return new std::function<std::unique_ptr<IndirectStubsManager>()>(+        llvm::orc::createLocalIndirectStubsManagerBuilder(Triple(triple)));+}++void LLVM_Hs_disposeIndirectStubsManagerBuilder(+    LLVMIndirectStubsManagerBuilderRef stubsManager) {+    delete stubsManager;+}++void LLVM_Hs_insertFun(std::set<llvm::Function *> *set,+                            llvm::Function *f) {+    set->insert(f);+}++LLVMCompileOnDemandLayerRef LLVM_Hs_createCompileOnDemandLayer(+    LLVMIRCompileLayerRef compileLayer,+    void (*partitioningFtor)(llvm::Function *, std::set<llvm::Function *> *set),+    LLVMJITCompileCallbackManagerRef callbackManager,+    LLVMIndirectStubsManagerBuilderRef stubsManager,+    LLVMBool cloneStubsIntoPartitions) {+    return new LLVMCompileOnDemandLayer(+        *compileLayer,+        [partitioningFtor](llvm::Function &f) -> std::set<llvm::Function *> {+            std::set<llvm::Function *> result;+            partitioningFtor(&f, &result);+            return result;+        },+        *callbackManager, *stubsManager, cloneStubsIntoPartitions);+}++void LLVM_Hs_disposeCompileOnDemandLayer(+    LLVMCompileOnDemandLayerRef codLayer) {+    delete codLayer;+}++LLVMCODModuleSetHandleRef LLVM_Hs_CompileOnDemandLayer_addModuleSet(+    LLVMCompileOnDemandLayerRef compileLayer, LLVMTargetDataRef dataLayout,+    LLVMModuleRef *modules, unsigned moduleCount,+    LLVMLambdaResolverRef resolver) {+    std::vector<Module *> moduleVec =+        getModules(modules, moduleCount, dataLayout);+    // We need to copy the resolver to make the use of unique_ptr (required by+    // the LLVM API) safe+    std::unique_ptr<LLVMLambdaResolver> uniqueResolver(+        new LLVMLambdaResolver(*resolver));+    return new LLVMCompileOnDemandLayer::ModuleSetHandleT(+        compileLayer->addModuleSet(moduleVec,+                                   make_unique<SectionMemoryManager>(),+                                   std::move(uniqueResolver)));+}++void LLVM_Hs_CompileOnDemandLayer_removeModuleSet(+    LLVMCompileOnDemandLayerRef compileLayer,+    LLVMCODModuleSetHandleRef moduleSetHandle) {+    compileLayer->removeModuleSet(*moduleSetHandle);+    delete moduleSetHandle;+}++LLVMJITSymbolRef LLVM_Hs_CompileOnDemandLayer_findSymbol(+    LLVMCompileOnDemandLayerRef compileLayer, const char *name,+    LLVMBool exportedSymbolsOnly) {+    JITSymbol symbol = compileLayer->findSymbol(name, exportedSymbolsOnly);+    return new JITSymbol(symbol);+}+}
+ src/LLVM/Internal/FFI/PassManager.hs view
@@ -0,0 +1,134 @@+{-# LANGUAGE+  TemplateHaskell,+  ForeignFunctionInterface,+  CPP+  #-}++module LLVM.Internal.FFI.PassManager where++import LLVM.Prelude++import qualified Language.Haskell.TH as TH++import Foreign.Ptr+import Foreign.C++import LLVM.Internal.FFI.LLVMCTypes+import LLVM.Internal.FFI.PtrHierarchy+import LLVM.Internal.FFI.Cleanup+import LLVM.Internal.FFI.Module+import LLVM.Internal.FFI.Target+import LLVM.Internal.FFI.Transforms++import qualified LLVM.Transforms as G++data PassManager++foreign import ccall unsafe "LLVMCreatePassManager" createPassManager ::+  IO (Ptr PassManager)++foreign import ccall unsafe "LLVMDisposePassManager" disposePassManager ::+  Ptr PassManager -> IO ()++foreign import ccall unsafe "LLVMRunPassManager" runPassManager ::+  Ptr PassManager -> Ptr Module -> IO CUInt++foreign import ccall unsafe "LLVMCreateFunctionPassManagerForModule" createFunctionPassManagerForModule ::+  Ptr Module -> IO (Ptr PassManager)++foreign import ccall unsafe "LLVMInitializeFunctionPassManager" initializeFunctionPassManager ::+  Ptr PassManager -> IO CUInt++foreign import ccall unsafe "LLVMRunFunctionPassManager" runFunctionPassManager ::+  Ptr PassManager -> Ptr Value -> IO CUInt++foreign import ccall unsafe "LLVMFinalizeFunctionPassManager" finalizeFunctionPassManager ::+  Ptr PassManager -> IO CUInt++foreign import ccall unsafe "LLVMAddAnalysisPasses" addAnalysisPasses ::+  Ptr TargetMachine -> Ptr PassManager -> IO ()++foreign import ccall unsafe "LLVMAddTargetLibraryInfo" addTargetLibraryInfoPass' ::+  Ptr TargetLibraryInfo -> Ptr PassManager -> IO ()++addTargetLibraryInfoPass :: Ptr PassManager -> Ptr TargetLibraryInfo -> IO ()+addTargetLibraryInfoPass = flip addTargetLibraryInfoPass'++$(do+  let declareForeign :: TH.Name -> [TH.Type] -> TH.DecsQ+      declareForeign hName extraParams = do+        let n = TH.nameBase hName+            passTypeMapping :: TH.Type -> TH.TypeQ+            passTypeMapping t = case t of+              TH.ConT h | h == ''Word -> [t| CUInt |]+                        | h == ''G.GCOVVersion -> [t| CString |]+              -- some of the LLVM methods for making passes use "-1" as a special value+              -- handle those here+              TH.AppT (TH.ConT mby) t' | mby == ''Maybe ->+                case t' of+                  TH.ConT h | h == ''Bool -> [t| NothingAsMinusOne Bool |]+                            | h == ''Word -> [t| NothingAsMinusOne Word |]+                            | h == ''FilePath -> [t| NothingAsEmptyString CString |]+                  _ -> typeMapping t+              _ -> typeMapping t+        foreignDecl+          (cName n)+          ("add" ++ n ++ "Pass")+          ([[t| Ptr PassManager |]]+           ++ [[t| Ptr TargetMachine |] | needsTargetMachine n]+           ++ map passTypeMapping extraParams)+          (TH.tupleT 0)+#if __GLASGOW_HASKELL__ < 800+  TH.TyConI (TH.DataD _ _ _ cons _) <- TH.reify ''G.Pass+#else+  TH.TyConI (TH.DataD _ _ _ _ cons _) <- TH.reify ''G.Pass+#endif+  liftM concat $ forM cons $ \con -> case con of+    TH.RecC n l -> declareForeign n [ t | (_,_,t) <- l ]+    TH.NormalC n [] -> declareForeign n []+    TH.NormalC n _ -> error "pass descriptor constructors with fields need to be records"+ )++data PassManagerBuilder++foreign import ccall unsafe "LLVMPassManagerBuilderCreate" passManagerBuilderCreate ::+    IO (Ptr PassManagerBuilder)++foreign import ccall unsafe "LLVMPassManagerBuilderDispose" passManagerBuilderDispose ::+    Ptr PassManagerBuilder -> IO ()++foreign import ccall unsafe "LLVMPassManagerBuilderSetOptLevel" passManagerBuilderSetOptLevel ::+    Ptr PassManagerBuilder -> CUInt -> IO ()++foreign import ccall unsafe "LLVMPassManagerBuilderSetSizeLevel" passManagerBuilderSetSizeLevel ::+    Ptr PassManagerBuilder -> CUInt -> IO ()++foreign import ccall unsafe "LLVMPassManagerBuilderSetDisableUnitAtATime" passManagerBuilderSetDisableUnitAtATime ::+    Ptr PassManagerBuilder -> LLVMBool -> IO ()++foreign import ccall unsafe "LLVMPassManagerBuilderSetDisableUnrollLoops" passManagerBuilderSetDisableUnrollLoops ::+    Ptr PassManagerBuilder -> CUInt -> IO ()++foreign import ccall unsafe "LLVMPassManagerBuilderSetDisableSimplifyLibCalls" passManagerBuilderSetDisableSimplifyLibCalls ::+    Ptr PassManagerBuilder -> LLVMBool -> IO ()++foreign import ccall unsafe "LLVMPassManagerBuilderUseInlinerWithThreshold" passManagerBuilderUseInlinerWithThreshold ::+    Ptr PassManagerBuilder -> CUInt -> IO ()++foreign import ccall unsafe "LLVMPassManagerBuilderPopulateFunctionPassManager" passManagerBuilderPopulateFunctionPassManager ::+    Ptr PassManagerBuilder -> Ptr PassManager -> IO ()++foreign import ccall unsafe "LLVMPassManagerBuilderPopulateModulePassManager" passManagerBuilderPopulateModulePassManager ::+    Ptr PassManagerBuilder -> Ptr PassManager -> IO ()++foreign import ccall unsafe "LLVMPassManagerBuilderPopulateLTOPassManager" passManagerBuilderPopulateLTOPassManager ::+    Ptr PassManagerBuilder -> Ptr PassManager -> CUChar -> CUChar -> IO ()++foreign import ccall unsafe "LLVM_Hs_PassManagerBuilderSetLibraryInfo" passManagerBuilderSetLibraryInfo ::+    Ptr PassManagerBuilder -> Ptr TargetLibraryInfo -> IO ()++foreign import ccall unsafe "LLVM_Hs_PassManagerBuilderSetLoopVectorize" passManagerBuilderSetLoopVectorize ::+    Ptr PassManagerBuilder -> LLVMBool -> IO ()++foreign import ccall unsafe "LLVM_Hs_PassManagerBuilderSetSuperwordLevelParallelismVectorize" passManagerBuilderSetSuperwordLevelParallelismVectorize ::+    Ptr PassManagerBuilder -> LLVMBool -> IO ()
+ src/LLVM/Internal/FFI/PassManagerC.cpp view
@@ -0,0 +1,248 @@+#define __STDC_LIMIT_MACROS+#include "llvm/IR/LLVMContext.h"+#include "llvm/IR/DataLayout.h"+#include "llvm/IR/LegacyPassManager.h"+#include "llvm/Transforms/Scalar.h"+#include "llvm/Transforms/Scalar/GVN.h"+#include "llvm/Transforms/IPO.h"+#include "llvm/Transforms/IPO/Internalize.h"+#include "llvm/Transforms/IPO/PassManagerBuilder.h"+#include "llvm/Transforms/Vectorize.h"+#include "llvm/Transforms/Instrumentation.h"+#include "llvm/CodeGen/Passes.h"+#include "llvm-c/Target.h"+#include "llvm-c/Transforms/PassManagerBuilder.h"+#include "llvm/Analysis/TargetLibraryInfo.h"+#include "llvm/Target/TargetMachine.h"++#include "llvm-c/Core.h"++using namespace llvm;++extern "C" {+typedef struct LLVMOpaqueVectorizationConfig *LLVMVectorizationConfigRef;+typedef struct LLVMOpaqueTargetLowering *LLVMTargetLoweringRef;+typedef struct LLVMOpaqueTargetMachine *LLVMTargetMachineRef;+}++namespace llvm {+inline TargetLowering *unwrap(LLVMTargetLoweringRef P) { +	return reinterpret_cast<TargetLowering *>(P);+}++inline LLVMTargetLoweringRef wrap(const TargetLowering *P) { +	return reinterpret_cast<LLVMTargetLoweringRef>(const_cast<TargetLowering *>(P));+}++inline TargetMachine *unwrap(LLVMTargetMachineRef P) {+	return reinterpret_cast<TargetMachine*>(P);+}++inline LLVMTargetMachineRef wrap(const TargetMachine *P) {+	return reinterpret_cast<LLVMTargetMachineRef>(const_cast<TargetMachine *>(P));+}++// Taken from llvm/lib/Transforms/IPO/PassManagerBuilder.cpp+inline PassManagerBuilder *unwrap(LLVMPassManagerBuilderRef P) {+    return reinterpret_cast<PassManagerBuilder*>(P);+}++inline TargetLibraryInfoImpl *unwrap(LLVMTargetLibraryInfoRef P) {+  return reinterpret_cast<TargetLibraryInfoImpl*>(P);+}++}++extern "C" {++#define LLVM_HS_FOR_EACH_PASS_WITHOUT_LLVM_C_BINDING(macro) \+	macro(BreakCriticalEdges) \+	macro(DeadCodeElimination) \+	macro(DeadInstElimination) \+	macro(DemoteRegisterToMemory) \+	macro(LCSSA) \+	macro(LoopInstSimplify) \+	macro(LowerAtomic) \+	macro(LowerSwitch) \+	macro(MergeFunctions) \+	macro(PartialInlining) \+	macro(Sinking) \+	macro(StripDeadDebugInfo) \+	macro(StripDebugDeclare) \+	macro(StripNonDebugSymbols) \++#define ENUM_CASE(p)								\+void LLVM_Hs_Add ## p ## Pass(LLVMPassManagerRef PM) {	\+	unwrap(PM)->add(create ## p ## Pass());			\+}+LLVM_HS_FOR_EACH_PASS_WITHOUT_LLVM_C_BINDING(ENUM_CASE)+#undef ENUM_CASE++void LLVM_Hs_AddCodeGenPreparePass(LLVMPassManagerRef PM, LLVMTargetMachineRef T) {+	unwrap(PM)->add(createCodeGenPreparePass(unwrap(T)));+}+	+void LLVM_Hs_AddGlobalValueNumberingPass(LLVMPassManagerRef PM, LLVMBool noLoads) {+	unwrap(PM)->add(createGVNPass(noLoads));+}++void LLVM_Hs_AddInternalizePass(LLVMPassManagerRef PM, unsigned nExports, const char **exports) {+    std::vector<std::string> exportList(nExports);+    for (unsigned i = 0; i < nExports; ++i) {+        exportList.at(i) = exports[i];+    }+    std::function<bool(const GlobalValue &)> mustPreserveGV = [exportList](const GlobalValue & gv) {+        for (const auto& exp : exportList) {+            if (gv.getName().equals(exp)) {+                return true;+            }+        }+        return false;+    };+    unwrap(PM)->add(createInternalizePass(std::move(mustPreserveGV)));+}++void LLVM_Hs_AddLoopStrengthReducePass(LLVMPassManagerRef PM) {+	unwrap(PM)->add(createLoopStrengthReducePass());+}++void LLVM_Hs_AddLowerInvokePass(LLVMPassManagerRef PM) {+	unwrap(PM)->add(createLowerInvokePass());+}+	+void LLVM_Hs_AddSROAPass(LLVMPassManagerRef PM) {+	unwrap(PM)->add(createSROAPass());+}++void LLVM_Hs_AddBasicBlockVectorizePass(+	LLVMPassManagerRef PM,+	unsigned vectorBits,+	LLVMBool vectorizeBools,+	LLVMBool vectorizeInts,+	LLVMBool vectorizeFloats,+	LLVMBool vectorizePointers,+	LLVMBool vectorizeCasts,+	LLVMBool vectorizeMath,+	LLVMBool vectorizeFusedMultiplyAdd,+	LLVMBool vectorizeSelect,+	LLVMBool vectorizeCmp,+	LLVMBool vectorizeGetElementPtr,+	LLVMBool vectorizeMemoryOperations,+	LLVMBool alignedOnly,+	unsigned reqChainDepth,+	unsigned searchLimit,+	unsigned maxCandidatePairsForCycleCheck,+	LLVMBool splatBreaksChain,+	unsigned maxInstructions,+	unsigned maxIterations,+	LLVMBool powerOfTwoLengthsOnly,+	LLVMBool noMemoryOperationBoost,+	LLVMBool fastDependencyAnalysis+) {+	VectorizeConfig vectorizeConfig;+	vectorizeConfig.VectorBits = vectorBits;+	vectorizeConfig.VectorizeBools = vectorizeBools;+	vectorizeConfig.VectorizeInts = vectorizeInts;+	vectorizeConfig.VectorizeFloats = vectorizeFloats;+	vectorizeConfig.VectorizePointers = vectorizePointers;+	vectorizeConfig.VectorizeCasts = vectorizeCasts;+	vectorizeConfig.VectorizeMath = vectorizeMath;+	vectorizeConfig.VectorizeFMA = vectorizeFusedMultiplyAdd;+	vectorizeConfig.VectorizeSelect = vectorizeSelect;+	vectorizeConfig.VectorizeCmp = vectorizeCmp;+	vectorizeConfig.VectorizeGEP = vectorizeGetElementPtr;+	vectorizeConfig.VectorizeMemOps = vectorizeMemoryOperations;+	vectorizeConfig.AlignedOnly = alignedOnly;+	vectorizeConfig.ReqChainDepth = reqChainDepth;+	vectorizeConfig.SearchLimit = searchLimit;+	vectorizeConfig.MaxCandPairsForCycleCheck = maxCandidatePairsForCycleCheck;+	vectorizeConfig.SplatBreaksChain = splatBreaksChain;+	vectorizeConfig.MaxInsts = maxInstructions;+	vectorizeConfig.MaxIter = maxIterations;+	vectorizeConfig.Pow2LenOnly = powerOfTwoLengthsOnly;+	vectorizeConfig.NoMemOpBoost = noMemoryOperationBoost;+	vectorizeConfig.FastDep = fastDependencyAnalysis;	++	unwrap(PM)->add(createBBVectorizePass(vectorizeConfig));+}++void LLVM_Hs_AddGCOVProfilerPass(+	LLVMPassManagerRef PM,+	LLVMBool emitNotes,+	LLVMBool emitData,+	const char *version,+	LLVMBool useCfgChecksum,+	LLVMBool noRedZone,+	LLVMBool functionNamesInData+) {+	struct GCOVOptions options;+	options.EmitNotes = emitNotes;+	options.EmitData = emitData;+	std::copy(version, version+4, options.Version);+	options.UseCfgChecksum = useCfgChecksum;+	options.NoRedZone = noRedZone;+	options.FunctionNamesInData = functionNamesInData;+	unwrap(PM)->add(createGCOVProfilerPass(options));+}++void LLVM_Hs_AddAddressSanitizerFunctionPass(+	LLVMPassManagerRef PM+) {+	unwrap(PM)->add(createAddressSanitizerFunctionPass());+}++void LLVM_Hs_AddAddressSanitizerModulePass(+	LLVMPassManagerRef PM+) {+	unwrap(PM)->add(createAddressSanitizerModulePass());+}++void LLVM_Hs_AddMemorySanitizerPass(+	LLVMPassManagerRef PM,+	LLVMBool trackOrigins+) {+	unwrap(PM)->add(createMemorySanitizerPass(trackOrigins));+}++void LLVM_Hs_AddThreadSanitizerPass(+	LLVMPassManagerRef PM+) {+	unwrap(PM)->add(createThreadSanitizerPass());+}++void LLVM_Hs_AddBoundsCheckingPass(LLVMPassManagerRef PM) {+	unwrap(PM)->add(createBoundsCheckingPass());+}++void LLVM_Hs_AddLoopVectorizePass(+	LLVMPassManagerRef PM,+	LLVMBool noUnrolling,+	LLVMBool alwaysVectorize+) {+	unwrap(PM)->add(createLoopVectorizePass(noUnrolling, alwaysVectorize));+}++void LLVM_Hs_PassManagerBuilderSetLibraryInfo(+	LLVMPassManagerBuilderRef PMB,+	LLVMTargetLibraryInfoRef l+) {+	// The PassManager frees the TargetLibraryInfo when done,+	// but we also free our ref, so give it a new copy.+	unwrap(PMB)->LibraryInfo = new TargetLibraryInfoImpl(*unwrap(l));+}++void LLVM_Hs_PassManagerBuilderSetLoopVectorize(+	LLVMPassManagerBuilderRef PMB,+	LLVMBool runLoopVectorization+) {+	unwrap(PMB)->LoopVectorize = runLoopVectorization;+}++void LLVM_Hs_PassManagerBuilderSetSuperwordLevelParallelismVectorize(+	LLVMPassManagerBuilderRef PMB,+	LLVMBool runSLPVectorization+) {+	unwrap(PMB)->SLPVectorize = runSLPVectorization;+}++}
+ src/LLVM/Internal/FFI/PtrHierarchy.hs view
@@ -0,0 +1,134 @@+{-# LANGUAGE+  ForeignFunctionInterface,+  MultiParamTypeClasses,+  FunctionalDependencies,+  UndecidableInstances,+  CPP+  #-}+#if __GLASGOW_HASKELL__ < 710+{-# LANGUAGE OverlappingInstances #-}+#define CPP_OVERLAPPING+#else+#define CPP_OVERLAPPING {-# OVERLAPPING #-}+#endif+-- | This module defines typeclasses to represent the relationships of an object-oriented inheritance hierarchy+module LLVM.Internal.FFI.PtrHierarchy where++import LLVM.Prelude++import Foreign.Ptr++-- | a class to represent safe casting of pointers to objects of descendant-classes to ancestor-classes.+class DescendentOf a b where+    upCast :: Ptr b -> Ptr a+    upCast = castPtr++-- | trivial casts+instance CPP_OVERLAPPING DescendentOf a a where+    upCast = id++-- | a class to represent direct parent-child relationships+class ChildOf b c | c -> b++-- | ancestor-descentant relationships are build out of parent-child relationships+instance (DescendentOf a b, ChildOf b c) => DescendentOf a c++-- | <http://llvm.org/doxygen/classllvm_1_1Value.html>+data Value++-- | <http://llvm.org/doxygen/classllvm_1_1Constant.html>+data Constant++instance ChildOf User Constant++-- | <http://llvm.org/doxygen/classllvm_1_1GlobalValue.html>+data GlobalValue++instance ChildOf Constant GlobalValue++-- | <http://llvm.org/doxygen/classllvm_1_1GlobalObject.html>+data GlobalObject++instance ChildOf GlobalValue GlobalObject++-- | <http://llvm.org/doxygen/classllvm_1_1GlobalVariable.html>+data GlobalVariable++instance ChildOf GlobalObject GlobalVariable++-- | <http://llvm.org/doxygen/classllvm_1_1GlobalAlias.html>+data GlobalAlias++instance ChildOf GlobalValue GlobalAlias++-- | <http://llvm.org/doxygen/classllvm_1_1Function.html>+data Function++instance ChildOf GlobalObject Function++-- | <http://llvm.org/doxygen/classllvm_1_1BasicBlock.html>+data BasicBlock++instance ChildOf Value BasicBlock++-- | <http://llvm.org/doxygen/classllvm_1_1Argument.html>+data Parameter++instance ChildOf Value Parameter++-- | <http://llvm.org/doxygen/classllvm_1_1Instruction.html>+data Instruction++instance ChildOf User Instruction++-- | <http://llvm.org/doxygen/classllvm_1_1BinaryOperator.html>+data BinaryOperator++instance ChildOf Instruction BinaryOperator++-- | <http://llvm.org/doxygen/classllvm_1_1User.html>+data User++instance ChildOf Value User++-- | <http://llvm.org/doxygen/classllvm_1_1MDNode.html>+data MDNode++instance ChildOf Metadata MDNode++-- | <http://llvm.org/doxygen/classllvm_1_1MDString.html>+data MDString++instance ChildOf Metadata MDString++-- | http://llvm.org/doxygen/classllvm_1_1ValueAsMetadata.html+data MDValue++instance ChildOf Metadata MDValue++-- | <http://llvm.org/doxygen/classllvm_1_1NamedMDNode.html>+data NamedMetadata++-- | <http://llvm.org/doxygen/classllvm_1_1InlineAsm.html>+data InlineAsm++instance ChildOf Value InlineAsm++-- | <http://llvm.org/doxygen/classllvm_1_1Type.html>+data Type++-- | <http://llvm.org/doxygen/classllvm_1_1Metadata.html>+data Metadata++-- | <http://www.llvm.org/docs/doxygen/html/classllvm_1_1MetadataAsValue.html>+data MetadataAsVal++instance ChildOf Value MetadataAsVal++-- | <http://llvm.org/docs/doxygen/html/classllvm_1_1raw__ostream.html>+data RawOStream++-- | <http://llvm.org/docs/doxygen/html/classllvm_1_1raw__pwrite__stream.html>+data RawPWriteStream++instance ChildOf RawOStream RawPWriteStream
+ src/LLVM/Internal/FFI/RawOStream.hs view
@@ -0,0 +1,35 @@+{-# LANGUAGE+  ForeignFunctionInterface+  #-}+module LLVM.Internal.FFI.RawOStream where++import LLVM.Prelude++import Foreign.Ptr+import Foreign.C+import Control.Exception (bracket)++import LLVM.Internal.FFI.ByteRangeCallback+import LLVM.Internal.FFI.LLVMCTypes+import LLVM.Internal.FFI.PtrHierarchy++type RawPWriteStreamCallback = Ptr RawPWriteStream -> IO ()++foreign import ccall "wrapper" wrapRawPWriteStreamCallback ::+  RawPWriteStreamCallback -> IO (FunPtr RawPWriteStreamCallback)++foreign import ccall safe "LLVM_Hs_WithFileRawPWriteStream" withFileRawPWriteStream' ::+  CString -> LLVMBool -> LLVMBool -> Ptr (OwnerTransfered CString) -> FunPtr RawPWriteStreamCallback -> IO LLVMBool++withFileRawPWriteStream :: CString -> LLVMBool -> LLVMBool -> Ptr (OwnerTransfered CString) -> RawPWriteStreamCallback -> IO LLVMBool+withFileRawPWriteStream p ex bin err c =+  bracket (wrapRawPWriteStreamCallback c) freeHaskellFunPtr (withFileRawPWriteStream' p ex bin err)++foreign import ccall safe "LLVM_Hs_WithBufferRawPWriteStream" withBufferRawPWriteStream' ::+  FunPtr ByteRangeCallback -> FunPtr RawPWriteStreamCallback -> IO ()++withBufferRawPWriteStream :: ByteRangeCallback -> RawPWriteStreamCallback -> IO ()+withBufferRawPWriteStream oc c =+  bracket (wrapRawPWriteStreamCallback c) freeHaskellFunPtr $ \c ->+  bracket (wrapByteRangeCallback oc) freeHaskellFunPtr $ \oc ->+    withBufferRawPWriteStream' oc c
+ src/LLVM/Internal/FFI/RawOStreamC.cpp view
@@ -0,0 +1,36 @@+#define __STDC_LIMIT_MACROS+#include "llvm-c/Core.h"+#include "llvm/Support/FileSystem.h"+#include "llvm/Support/raw_ostream.h"++using namespace llvm;+using sys::fs::F_None;+using sys::fs::F_Excl;+using sys::fs::F_Text;++extern "C" {++LLVMBool+LLVM_Hs_WithFileRawPWriteStream(const char *filename, LLVMBool excl,+                                LLVMBool text, char **error,+                                void (&callback)(raw_pwrite_stream &ostream)) {+    std::error_code e;+    raw_fd_ostream os(filename, e,+                      (excl ? F_Excl : F_None) | (text ? F_Text : F_None));+    if (e) {+        *error = strdup(e.message().c_str());+        return false;+    }+    callback(os);+    return true;+}++void LLVM_Hs_WithBufferRawPWriteStream(+    void (&outputCallback)(const char *start, size_t length),+    void (&streamCallback)(raw_pwrite_stream &ostream)) {+    SmallString<0> s;+    raw_svector_ostream os(s);+    streamCallback(os);+    outputCallback(os.str().data(), s.size());+}+}
+ src/LLVM/Internal/FFI/SMDiagnostic.h view
@@ -0,0 +1,15 @@+#ifndef __LLVM_INTERNAL_FFI__SMDIAGNOSTIC__+#define __LLVM_INTERNAL_FFI__SMDIAGNOSTIC__++#define LLVM_HS_FOR_EACH_DIAGNOSTIC_KIND(macro) \+	macro(Error) \+	macro(Warning) \+	macro(Note)++typedef enum {+#define ENUM_CASE(k) LLVMDiagnosticKind ## k,+LLVM_HS_FOR_EACH_DIAGNOSTIC_KIND(ENUM_CASE)+#undef ENUM_CASE+} LLVMDiagnosticKind;++#endif
+ src/LLVM/Internal/FFI/SMDiagnostic.hs view
@@ -0,0 +1,40 @@+{-# LANGUAGE+  ForeignFunctionInterface+  #-}+-- | FFI functions for handling the LLVM SMDiagnostic class+module LLVM.Internal.FFI.SMDiagnostic where++import LLVM.Prelude++import Foreign.Ptr+import Foreign.C++import LLVM.Internal.FFI.LLVMCTypes++data SMDiagnostic++-- | allocate an SMDiagnostic object+foreign import ccall unsafe "LLVM_Hs_CreateSMDiagnostic" createSMDiagnostic ::+  IO (Ptr SMDiagnostic)++foreign import ccall unsafe "LLVM_Hs_DisposeSMDiagnostic" disposeSMDiagnostic ::+  Ptr SMDiagnostic -> IO ()++foreign import ccall unsafe "LLVM_Hs_GetSMDiagnosticKind" getSMDiagnosticKind ::+  Ptr SMDiagnostic -> IO DiagnosticKind++foreign import ccall unsafe "LLVM_Hs_GetSMDiagnosticLineNo" getSMDiagnosticLineNo ::+  Ptr SMDiagnostic -> IO CInt ++foreign import ccall unsafe "LLVM_Hs_GetSMDiagnosticColumnNo" getSMDiagnosticColumnNo ::+  Ptr SMDiagnostic -> IO CInt ++foreign import ccall unsafe "LLVM_Hs_GetSMDiagnosticFilename" getSMDiagnosticFilename ::+  Ptr SMDiagnostic -> Ptr CUInt -> IO CString ++foreign import ccall unsafe "LLVM_Hs_GetSMDiagnosticMessage" getSMDiagnosticMessage ::+  Ptr SMDiagnostic -> Ptr CUInt -> IO CString ++foreign import ccall unsafe "LLVM_Hs_GetSMDiagnosticLineContents" getSMDiagnosticLineContents ::+  Ptr SMDiagnostic -> Ptr CUInt -> IO CString +
+ src/LLVM/Internal/FFI/SMDiagnosticC.cpp view
@@ -0,0 +1,42 @@+#define __STDC_LIMIT_MACROS+#include "llvm/Config/llvm-config.h"+#include "llvm/IR/LLVMContext.h"++#include "llvm/Support/SourceMgr.h"+#include "llvm-c/Core.h"++#include "LLVM/Internal/FFI/SMDiagnostic.h"++using namespace llvm;++extern "C" {++SMDiagnostic *LLVM_Hs_CreateSMDiagnostic() { return new SMDiagnostic(); }+void LLVM_Hs_DisposeSMDiagnostic(SMDiagnostic *p) { delete p; }++LLVMDiagnosticKind LLVM_Hs_GetSMDiagnosticKind(SMDiagnostic *p) {+	switch(p->getKind()) {+#define ENUM_CASE(k) case SourceMgr::DK_ ## k: return LLVMDiagnosticKind ## k;+		LLVM_HS_FOR_EACH_DIAGNOSTIC_KIND(ENUM_CASE)+#undef ENUM_CASE+	default: return LLVMDiagnosticKind(0);+	}+}++int LLVM_Hs_GetSMDiagnosticLineNo(SMDiagnostic *p) { return p->getLineNo(); }+int LLVM_Hs_GetSMDiagnosticColumnNo(SMDiagnostic *p) { return p->getColumnNo(); }++const char *LLVM_Hs_GetSMDiagnosticFilename(SMDiagnostic *p, unsigned *len) { +	*len = p->getFilename().size();+	return p->getFilename().data();+}+const char *LLVM_Hs_GetSMDiagnosticMessage(SMDiagnostic *p, unsigned *len) {+	*len = p->getMessage().size();+	return p->getMessage().data();+}+const char *LLVM_Hs_GetSMDiagnosticLineContents(SMDiagnostic *p, unsigned *len) {+	*len = p->getLineContents().size();+	return p->getLineContents().data();+}++}
+ src/LLVM/Internal/FFI/Target.h view
@@ -0,0 +1,71 @@+#ifndef __LLVM_INTERNAL_FFI__TARGET__H__+#define __LLVM_INTERNAL_FFI__TARGET__H__++#define LLVM_HS_FOR_EACH_RELOC_MODEL(macro)	\+	macro(Default, Default)													\+	macro(Static, Static)														\+	macro(PIC, PIC_)																\+	macro(DynamicNoPic, DynamicNoPIC)++#define LLVM_HS_FOR_EACH_CODE_MODEL(macro) \+	macro(Default)																\+	macro(JITDefault)															\+	macro(Small)																	\+	macro(Kernel)																	\+	macro(Medium)																	\+	macro(Large)++#define LLVM_HS_FOR_EACH_CODE_GEN_OPT_LEVEL(macro) \+	macro(None)																						\+	macro(Less)																						\+	macro(Default)																				\+	macro(Aggressive)++#define LLVM_HS_FOR_EACH_CODE_GEN_FILE_TYPE(macro)	\+	macro(Assembly)                                       \+	macro(Object)++#define LLVM_HS_FOR_EACH_TARGET_OPTION_FLAG(macro)	\+	macro(PrintMachineCode)																\+	macro(LessPreciseFPMADOption)													\+	macro(UnsafeFPMath)																		\+	macro(NoInfsFPMath)																		\+	macro(NoNaNsFPMath)																		\+	macro(HonorSignDependentRoundingFPMathOption)					\+	macro(NoZerosInBSS)																		\+	macro(GuaranteedTailCallOpt)													\+	macro(EnableFastISel)																	\+	macro(UseInitArray)																		\+	macro(DisableIntegratedAS)														\+	macro(CompressDebugSections)													\+	macro(TrapUnreachable)++typedef enum {+#define ENUM_CASE(n) LLVM_Hs_TargetOptionFlag_ ## n,+	LLVM_HS_FOR_EACH_TARGET_OPTION_FLAG(ENUM_CASE)+#undef ENUM_CASE+} LLVM_Hs_TargetOptionFlag;++#define LLVM_HS_FOR_EACH_FLOAT_ABI(macro)	\+	macro(Default)																\+	macro(Soft)																		\+	macro(Hard)++typedef enum {+#define ENUM_CASE(n) LLVM_Hs_FloatABI_ ## n,+	LLVM_HS_FOR_EACH_FLOAT_ABI(ENUM_CASE)+#undef ENUM_CASE+} LLVM_Hs_FloatABI;++#define LLVM_HS_FOR_EACH_FP_OP_FUSION_MODE(macro)	\+	macro(Fast)																						\+	macro(Standard)																				\+	macro(Strict)++typedef enum {+#define ENUM_CASE(n) LLVM_Hs_FPOpFusionMode_ ## n,+	LLVM_HS_FOR_EACH_FP_OP_FUSION_MODE(ENUM_CASE)+#undef ENUM_CASE+} LLVM_Hs_FPOpFusionMode;++#endif
+ src/LLVM/Internal/FFI/Target.hpp view
@@ -0,0 +1,11 @@+#ifndef __LLVM_INTERNAL_FFI__TARGET__HPP__+#define __LLVM_INTERNAL_FFI__TARGET__HPP__++#include "llvm-c/TargetMachine.h"+#include "llvm/Target/TargetMachine.h"++namespace llvm {+DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)+}++#endif
+ src/LLVM/Internal/FFI/Target.hs view
@@ -0,0 +1,141 @@+{-# LANGUAGE+  ForeignFunctionInterface,+  GeneralizedNewtypeDeriving+  #-}+module LLVM.Internal.FFI.Target where++import LLVM.Prelude++import Foreign.Ptr+import Foreign.C++import LLVM.Internal.FFI.DataLayout+import LLVM.Internal.FFI.LLVMCTypes+import LLVM.Internal.FFI.MemoryBuffer+import LLVM.Internal.FFI.Module+import LLVM.Internal.FFI.PtrHierarchy++data Target++foreign import ccall unsafe "LLVM_Hs_InitializeNativeTarget" initializeNativeTarget ::+    IO LLVMBool++foreign import ccall unsafe "LLVM_Hs_LookupTarget" lookupTarget ::+    CString -> CString -> Ptr (OwnerTransfered CString) -> Ptr (OwnerTransfered CString) -> IO (Ptr Target)++data TargetOptions++foreign import ccall unsafe "LLVM_Hs_CreateTargetOptions" createTargetOptions ::+  IO (Ptr TargetOptions)++foreign import ccall unsafe "LLVM_Hs_SetTargetOptionFlag" setTargetOptionFlag ::+  Ptr TargetOptions -> TargetOptionFlag -> LLVMBool -> IO ()++foreign import ccall unsafe "LLVM_Hs_GetTargetOptionFlag" getTargetOptionsFlag ::+  Ptr TargetOptions -> TargetOptionFlag -> IO LLVMBool++foreign import ccall unsafe "LLVM_Hs_SetStackAlignmentOverride" setStackAlignmentOverride ::+  Ptr TargetOptions -> CUInt -> IO ()++foreign import ccall unsafe "LLVM_Hs_GetStackAlignmentOverride" getStackAlignmentOverride ::+  Ptr TargetOptions -> IO CUInt++foreign import ccall unsafe "LLVM_Hs_SetFloatABIType" setFloatABIType ::+  Ptr TargetOptions -> FloatABIType -> IO ()++foreign import ccall unsafe "LLVM_Hs_GetFloatABIType" getFloatABIType ::+  Ptr TargetOptions -> IO FloatABIType++foreign import ccall unsafe "LLVM_Hs_SetAllowFPOpFusion" setAllowFPOpFusion ::+  Ptr TargetOptions -> FPOpFusionMode -> IO ()++foreign import ccall unsafe "LLVM_Hs_GetAllowFPOpFusion" getAllowFPOpFusion ::+  Ptr TargetOptions -> IO FPOpFusionMode++foreign import ccall unsafe "LLVM_Hs_DisposeTargetOptions" disposeTargetOptions ::+  Ptr TargetOptions -> IO ()++data TargetMachine++foreign import ccall unsafe "LLVMCreateTargetMachine" createTargetMachine ::+  Ptr Target+  -> CString+  -> CString+  -> CString+  -> Ptr TargetOptions+  -> RelocModel+  -> CodeModel+  -> CodeGenOptLevel+  -> IO (Ptr TargetMachine)++foreign import ccall unsafe "LLVMDisposeTargetMachine" disposeTargetMachine ::+  Ptr TargetMachine -> IO ()++foreign import ccall unsafe "LLVM_Hs_TargetMachineEmit" targetMachineEmit ::+  Ptr TargetMachine+  -> Ptr Module+  -> Ptr RawPWriteStream+  -> CodeGenFileType+  -> Ptr (OwnerTransfered CString)+  -> IO LLVMBool++foreign import ccall unsafe "LLVMTargetMachineEmitToFile" targetMachineEmitToFile ::+  Ptr TargetMachine+  -> Ptr Module+  -> CString+  -> CodeGenFileType+  -> Ptr (OwnerTransfered CString)+  -> IO LLVMBool++foreign import ccall unsafe "LLVMTargetMachineEmitToMemoryBuffer" targetMachineEmitToMemoryBuffer ::+  Ptr TargetMachine+  -> Ptr Module+  -> CodeGenFileType+  -> Ptr (OwnerTransfered CString)+  -> Ptr (Ptr MemoryBuffer)+  -> IO LLVMBool++data TargetLowering++-- foreign import ccall unsafe "LLVM_Hs_GetTargetLowering" getTargetLowering ::+--   Ptr TargetMachine -> IO (Ptr TargetLowering)++foreign import ccall unsafe "LLVMGetTargetMachineTriple" getTargetMachineTriple ::+  Ptr TargetMachine -> IO (OwnerTransfered CString)++foreign import ccall unsafe "LLVM_Hs_GetDefaultTargetTriple" getDefaultTargetTriple :: +  IO (OwnerTransfered CString)++foreign import ccall unsafe "LLVM_Hs_GetProcessTargetTriple" getProcessTargetTriple :: +  IO (OwnerTransfered CString)++foreign import ccall unsafe "LLVM_Hs_GetHostCPUName" getHostCPUName :: +  Ptr CSize -> IO CString++foreign import ccall unsafe "LLVM_Hs_GetHostCPUFeatures" getHostCPUFeatures ::+  IO (OwnerTransfered CString)++foreign import ccall unsafe "LLVM_Hs_GetTargetMachineDataLayout" getTargetMachineDataLayout ::+  Ptr TargetMachine -> IO (OwnerTransfered CString)++data TargetLibraryInfo++foreign import ccall unsafe "LLVM_Hs_CreateTargetLibraryInfo" createTargetLibraryInfo ::+  CString -> IO (Ptr TargetLibraryInfo)++foreign import ccall unsafe "LLVM_Hs_GetLibFunc" getLibFunc ::+  Ptr TargetLibraryInfo -> CString -> Ptr LibFunc -> IO LLVMBool++foreign import ccall unsafe "LLVM_Hs_LibFuncGetName" libFuncGetName ::+  Ptr TargetLibraryInfo -> LibFunc -> Ptr CSize -> IO CString++foreign import ccall unsafe "LLVM_Hs_LibFuncSetAvailableWithName" libFuncSetAvailableWithName ::+  Ptr TargetLibraryInfo -> LibFunc -> CString -> IO ()++foreign import ccall unsafe "LLVM_Hs_DisposeTargetLibraryInfo" disposeTargetLibraryInfo ::+  Ptr TargetLibraryInfo -> IO ()++foreign import ccall unsafe "LLVM_Hs_InitializeAllTargets" initializeAllTargets :: IO ()++foreign import ccall unsafe "LLVMCreateTargetDataLayout" createTargetDataLayout ::+  Ptr TargetMachine -> IO (Ptr DataLayout)
+ src/LLVM/Internal/FFI/TargetC.cpp view
@@ -0,0 +1,319 @@+#define __STDC_LIMIT_MACROS+#include "llvm-c/Target.h"+#include "LLVM/Internal/FFI/LibFunc.h"+#include "LLVM/Internal/FFI/Target.h"+#include "LLVM/Internal/FFI/Target.hpp"+#include "llvm-c/Core.h"+#include "llvm-c/TargetMachine.h"+#include "llvm/ADT/Triple.h"+#include "llvm/Analysis/TargetLibraryInfo.h"+#include "llvm/ExecutionEngine/Interpreter.h"+#include "llvm/IR/DataLayout.h"+#include "llvm/IR/LegacyPassManager.h"+#include "llvm/IR/Module.h"+#include "llvm/Support/FormattedStream.h"+#include "llvm/Support/Host.h"+#include "llvm/Support/TargetRegistry.h"+#include "llvm/Support/TargetSelect.h"+#include "llvm/Target/TargetMachine.h"++using namespace llvm;++namespace llvm {+// Taken from llvm/lib/Target/TargetMachineC.cpp+// These functions need to be marked as static to avoid undefined behavior+// due to multiple definitions+static LLVMTargetRef wrap(const Target *P) {+  return reinterpret_cast<LLVMTargetRef>(const_cast<Target *>(P));+}++static inline TargetLibraryInfoImpl *unwrap(LLVMTargetLibraryInfoRef P) {+  return reinterpret_cast<TargetLibraryInfoImpl*>(P);+}++static inline LLVMTargetLibraryInfoRef wrap(const TargetLibraryInfoImpl *P) {+  TargetLibraryInfoImpl *X = const_cast<TargetLibraryInfoImpl*>(P);+  return reinterpret_cast<LLVMTargetLibraryInfoRef>(X);+}++static FloatABI::ABIType unwrap(LLVM_Hs_FloatABI x) {+  switch (x) {+#define ENUM_CASE(x)                                                           \+  case LLVM_Hs_FloatABI_##x:                                              \+    return FloatABI::x;+    LLVM_HS_FOR_EACH_FLOAT_ABI(ENUM_CASE)+#undef ENUM_CASE+  default:+    return FloatABI::ABIType(0);+  }+}++static LibFunc::Func unwrap(LLVMLibFunc x) {+  switch (x) {+#define ENUM_CASE(x)                                                           \+  case LLVMLibFunc__##x:                                                       \+    return LibFunc::x;+    LLVM_HS_FOR_EACH_LIB_FUNC(ENUM_CASE)+#undef ENUM_CASE+  default:+    return LibFunc::Func(0);+  }+}++static LLVMLibFunc wrap(LibFunc::Func x) {+  switch (x) {+#define ENUM_CASE(x)                                                           \+  case LibFunc::x:                                                             \+    return LLVMLibFunc__##x;+    LLVM_HS_FOR_EACH_LIB_FUNC(ENUM_CASE)+#undef ENUM_CASE+  default:+    return LLVMLibFunc(0);+  }+}++static LLVM_Hs_FloatABI wrap(FloatABI::ABIType x) {+  switch (x) {+#define ENUM_CASE(x)                                                           \+  case FloatABI::x:                                                            \+    return LLVM_Hs_FloatABI_##x;+    LLVM_HS_FOR_EACH_FLOAT_ABI(ENUM_CASE)+#undef ENUM_CASE+  default:+    return LLVM_Hs_FloatABI(0);+  }+}++static FPOpFusion::FPOpFusionMode unwrap(LLVM_Hs_FPOpFusionMode x) {+  switch (x) {+#define ENUM_CASE(x)                                                           \+  case LLVM_Hs_FPOpFusionMode_##x:                                        \+    return FPOpFusion::x;+    LLVM_HS_FOR_EACH_FP_OP_FUSION_MODE(ENUM_CASE)+#undef ENUM_CASE+  default:+    return FPOpFusion::FPOpFusionMode(0);+  }+}++static LLVM_Hs_FPOpFusionMode wrap(FPOpFusion::FPOpFusionMode x) {+  switch (x) {+#define ENUM_CASE(x)                                                           \+  case FPOpFusion::x:                                                          \+    return LLVM_Hs_FPOpFusionMode_##x;+    LLVM_HS_FOR_EACH_FP_OP_FUSION_MODE(ENUM_CASE)+#undef ENUM_CASE+  default:+    return LLVM_Hs_FPOpFusionMode(0);+  }+}+}++extern "C" {++LLVMBool LLVM_Hs_InitializeNativeTarget() {+  return LLVMInitializeNativeTarget() || InitializeNativeTargetAsmPrinter() ||+         InitializeNativeTargetAsmParser();+}++LLVMTargetRef LLVM_Hs_LookupTarget(const char *arch, const char *ctriple,+                                        const char **tripleOut,+                                        const char **cerror) {+  std::string error;+  Triple triple(ctriple);+  if (const Target *result =+          TargetRegistry::lookupTarget(arch, triple, error)) {+    *tripleOut = strdup(triple.getTriple().c_str());+    return wrap(result);+  }+  *cerror = strdup(error.c_str());+  return 0;+}++TargetOptions *LLVM_Hs_CreateTargetOptions() {+  TargetOptions *to = new TargetOptions();+  return to;+}++void LLVM_Hs_SetTargetOptionFlag(TargetOptions *to,+                                      LLVM_Hs_TargetOptionFlag f,+                                      unsigned v) {+  switch (f) {+#define ENUM_CASE(op)                                                          \+  case LLVM_Hs_TargetOptionFlag_##op:                                     \+    to->op = v ? 1 : 0;                                                        \+    break;+    LLVM_HS_FOR_EACH_TARGET_OPTION_FLAG(ENUM_CASE)+#undef ENUM_CASE+  }+}++unsigned LLVM_Hs_GetTargetOptionFlag(TargetOptions *to,+                                          LLVM_Hs_TargetOptionFlag f) {+  switch (f) {+#define ENUM_CASE(op)                                                          \+  case LLVM_Hs_TargetOptionFlag_##op:                                     \+    return to->op;+    LLVM_HS_FOR_EACH_TARGET_OPTION_FLAG(ENUM_CASE)+#undef ENUM_CASE+  default:+    assert(false && "Unknown target option flag");+    return 0;+  }+}++void LLVM_Hs_SetStackAlignmentOverride(TargetOptions *to, unsigned v) {+  to->StackAlignmentOverride = v;+}++unsigned LLVM_Hs_GetStackAlignmentOverride(TargetOptions *to) {+  return to->StackAlignmentOverride;+}++void LLVM_Hs_SetFloatABIType(TargetOptions *to, LLVM_Hs_FloatABI v) {+  to->FloatABIType = unwrap(v);+}++LLVM_Hs_FloatABI LLVM_Hs_GetFloatABIType(TargetOptions *to) {+  return wrap(to->FloatABIType);+}++void LLVM_Hs_SetAllowFPOpFusion(TargetOptions *to,+                                     LLVM_Hs_FPOpFusionMode v) {+  to->AllowFPOpFusion = unwrap(v);+}++LLVM_Hs_FPOpFusionMode LLVM_Hs_GetAllowFPOpFusion(TargetOptions *to) {+  return wrap(to->AllowFPOpFusion);+}++void LLVM_Hs_DisposeTargetOptions(TargetOptions *t) { delete t; }++// const TargetLowering *LLVM_Hs_GetTargetLowering(LLVMTargetMachineRef t)+// {+// 	return unwrap(t)->getTargetLowering();+// }++char *LLVM_Hs_GetDefaultTargetTriple() {+  return strdup(sys::getDefaultTargetTriple().c_str());+}++char *LLVM_Hs_GetProcessTargetTriple() {+  return strdup(sys::getProcessTriple().c_str());+}++const char *LLVM_Hs_GetHostCPUName(size_t &len) {+  StringRef r = sys::getHostCPUName();+  len = r.size();+  return r.data();+}++char *LLVM_Hs_GetHostCPUFeatures() {+  StringMap<bool> featureMap;+  std::string features;+  if (sys::getHostCPUFeatures(featureMap)) {+    bool first = true;+    for (llvm::StringMap<bool>::const_iterator it = featureMap.begin();+         it != featureMap.end(); ++it) {+      if (!first) {+        features += ",";+      }+      first = false;+      features += (it->second ? "+" : "-") + it->first().str();+    }+  }+  return strdup(features.c_str());+}++char *LLVM_Hs_GetTargetMachineDataLayout(LLVMTargetMachineRef t) {+  return strdup(+      unwrap(t)->createDataLayout().getStringRepresentation().c_str());+}++LLVMTargetLibraryInfoRef+LLVM_Hs_CreateTargetLibraryInfo(const char *triple) {+    const TargetLibraryInfoImpl* p = new TargetLibraryInfoImpl(Triple(triple));+    return wrap(p);+}++LLVMBool LLVM_Hs_GetLibFunc(+	LLVMTargetLibraryInfoRef l,+	const char *funcName,+	LLVMLibFunc *f+) {+	LibFunc::Func func;+	LLVMBool result = unwrap(l)->getLibFunc(funcName, func);+	*f = wrap(func);+	return result;+}++const char *LLVM_Hs_LibFuncGetName(+	LLVMTargetLibraryInfoRef l,+	LLVMLibFunc f,+	size_t *nameSize+) {+	TargetLibraryInfo impl(*unwrap(l));+    StringRef s = impl.getName(unwrap(f));+	*nameSize = s.size();+	return s.data();+}++void LLVM_Hs_LibFuncSetAvailableWithName(+	LLVMTargetLibraryInfoRef l,+	LLVMLibFunc f,+	const char *name+) {+	unwrap(l)->setAvailableWithName(unwrap(f), name);+}++void LLVM_Hs_DisposeTargetLibraryInfo(LLVMTargetLibraryInfoRef l) {+	delete unwrap(l);+}++void LLVM_Hs_InitializeAllTargets() {+  InitializeAllTargetInfos();+  InitializeAllTargets();+  InitializeAllTargetMCs();+  InitializeAllAsmPrinters();+  // None of the other components are bound yet+}++// This is identical to LLVMTargetMachineEmit but LLVM doesn’t expose this function so we copy it here.+LLVMBool LLVM_Hs_TargetMachineEmit(+    LLVMTargetMachineRef T,+    LLVMModuleRef M,+    raw_pwrite_stream *OS,+    LLVMCodeGenFileType codegen,+    char **ErrorMessage+) {+  TargetMachine* TM = unwrap(T);+  Module* Mod = unwrap(M);++  legacy::PassManager pass;++  std::string error;++  Mod->setDataLayout(TM->createDataLayout());++  TargetMachine::CodeGenFileType ft;+  switch (codegen) {+    case LLVMAssemblyFile:+      ft = TargetMachine::CGFT_AssemblyFile;+      break;+    default:+      ft = TargetMachine::CGFT_ObjectFile;+      break;+  }+  if (TM->addPassesToEmitFile(pass, *OS, ft)) {+    error = "TargetMachine can't emit a file of this type";+    *ErrorMessage = strdup(error.c_str());+    return true;+  }++  pass.run(*Mod);++  OS->flush();+  return false;+}++}
+ src/LLVM/Internal/FFI/Threading.hs view
@@ -0,0 +1,13 @@+{-# LANGUAGE+  ForeignFunctionInterface+  #-}+module LLVM.Internal.FFI.Threading where++import LLVM.Prelude++import Foreign.C++import LLVM.Internal.FFI.LLVMCTypes++foreign import ccall unsafe "LLVMIsMultithreaded" isMultithreaded ::+  IO LLVMBool
+ src/LLVM/Internal/FFI/Transforms.hs view
@@ -0,0 +1,76 @@+-- | Code used with Template Haskell to build the FFI for transform passes.+module LLVM.Internal.FFI.Transforms where++import LLVM.Prelude++-- | does the constructor for this pass require a TargetMachine object+needsTargetMachine :: String -> Bool+needsTargetMachine "CodeGenPrepare" = True+needsTargetMachine _ = False++-- | Translate a Haskell name (used in the public Haskell interface, typically not abbreviated)+-- | for a pass into the (sometimes obscure, sometimes abbreviated) name used in the LLVM C interface.+-- | This translation includes, by choice of prefix, whether the C interface implementation is found in+-- | the LLVM distribution ("LLVM" prefix) or either not available or broken there and so implemented+-- | as part of this Haskell package ("LLVM_Hs_" prefix).+cName :: String -> String+cName n =+    let core = case n of+            "AddressSanitizer" -> "AddressSanitizerFunction"+            "AggressiveDeadCodeElimination" -> "AggressiveDCE"+            "AlwaysInline" -> "AlwaysInliner"+            "DeadInstructionElimination" -> "DeadInstElimination"+            "EarlyCommonSubexpressionElimination" -> "EarlyCSE"+            "FunctionAttributes" -> "FunctionAttrs"+            "GlobalDeadCodeElimination" -> "GlobalDCE"+            "InductionVariableSimplify" -> "IndVarSimplify"+            "InternalizeFunctions" -> "Internalize"+            "InterproceduralConstantPropagation" -> "IPConstantPropagation"+            "InterproceduralSparseConditionalConstantPropagation" -> "IPSCCP"+            "LoopClosedSingleStaticAssignment" -> "LCSSA"+            "LoopInvariantCodeMotion" -> "LICM"+            "LoopInstructionSimplify" -> "LoopInstSimplify"+            "MemcpyOptimization" -> "MemCpyOpt"+            "PruneExceptionHandling" -> "PruneEH"+            "ScalarReplacementOfAggregates" -> "SROA"+            "OldScalarReplacementOfAggregates" -> "ScalarReplAggregates"+            "SimplifyControlFlowGraph" -> "CFGSimplification"+            "SparseConditionalConstantPropagation" -> "SCCP"+            "SuperwordLevelParallelismVectorize" -> "SLPVectorize"+            h -> h+        patchImpls = [+         "AddressSanitizer",+         "AddressSanitizerModule",+         "BoundsChecking",+         "CodeGenPrepare",+         "GlobalValueNumbering",+         "InternalizeFunctions",+         "BasicBlockVectorize",+         "BlockPlacement",+         "BreakCriticalEdges",+         "DeadCodeElimination",+         "DeadInstructionElimination",+         "DemoteRegisterToMemory",+         "EdgeProfiler",+         "GCOVProfiler",+         "LoopClosedSingleStaticAssignment",+         "LoopInstructionSimplify",+         "LoopStrengthReduce",+         "LoopVectorize",+         "LowerAtomic",+         "LowerInvoke",+         "LowerSwitch",+         "MemorySanitizer",+         "MergeFunctions",+         "OptimalEdgeProfiler",+         "PathProfiler",+         "PartialInlining",+         "ScalarReplacementOfAggregates",+         "Sinking",+         "StripDeadDebugInfo",+         "StripDebugDeclare",+         "StripNonDebugSymbols",+         "ThreadSanitizer"+         ]+    in+      (if (n `elem` patchImpls) then "LLVM_Hs_" else "LLVM") ++ "Add" ++ core ++ "Pass"
+ src/LLVM/Internal/FFI/Type.h view
@@ -0,0 +1,23 @@+#ifndef __LLVM_INTERNAL_FFI__TYPE__H__+#define __LLVM_INTERNAL_FFI__TYPE__H__++#define LLVM_HS_FOR_EACH_TYPE_KIND(macro) \+	macro(Void) \+	macro(Half) \+	macro(Float) \+	macro(Double) \+	macro(X86_FP80) \+	macro(FP128) \+	macro(PPC_FP128) \+	macro(Label) \+	macro(Integer) \+	macro(Function) \+	macro(Struct) \+	macro(Array) \+	macro(Pointer) \+	macro(Vector) \+	macro(Metadata) \+	macro(X86_MMX) \+	macro(Token)++#endif
+ src/LLVM/Internal/FFI/Type.hs view
@@ -0,0 +1,152 @@+{-# LANGUAGE+  ForeignFunctionInterface+  #-}+-- | Functions for handling the LLVM types+module LLVM.Internal.FFI.Type where++import LLVM.Prelude++import Foreign.Ptr+import Foreign.C++import LLVM.Internal.FFI.LLVMCTypes+import LLVM.Internal.FFI.Context+import LLVM.Internal.FFI.PtrHierarchy++-- | <http://llvm.org/doxygen/group__LLVMCCoreType.html#ga112756467f0988613faa6043d674d843>+foreign import ccall unsafe "LLVMGetTypeKind" getTypeKind ::+  Ptr Type -> IO TypeKind++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeInt.html#gadfb8ba2f605f0860a4bf2e3c480ab6a2>+foreign import ccall unsafe "LLVMGetIntTypeWidth" getIntTypeWidth ::+  Ptr Type -> IO (CUInt)++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeFunction.html#ga2970f0f4d9ee8a0f811f762fb2fa7f82>+foreign import ccall unsafe "LLVMIsFunctionVarArg" isFunctionVarArg ::+  Ptr Type -> IO LLVMBool++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeFunction.html#gacfa4594cbff421733add602a413cae9f>+foreign import ccall unsafe "LLVMGetReturnType" getReturnType ::+  Ptr Type -> IO (Ptr Type)++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeFunction.html#ga44fa41d22ed1f589b8202272f54aad77>+foreign import ccall unsafe "LLVMCountParamTypes" countParamTypes ::+  Ptr Type -> IO CUInt++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeFunction.html#ga83dd3a49a0f3f017f4233fc0d667bda2>+foreign import ccall unsafe "LLVMGetParamTypes" getParamTypes ::+  Ptr Type -> Ptr (Ptr Type) -> IO ()++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeSequential.html#ga0b03e26a2d254530a9b5c279cdf52257>+foreign import ccall unsafe "LLVMGetElementType" getElementType ::+  Ptr Type -> IO (Ptr Type)++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeInt.html#ga2e5db8cbc30daa156083f2c42989138d>+foreign import ccall unsafe "LLVMIntTypeInContext" intTypeInContext ::+  Ptr Context -> CUInt -> IO (Ptr Type)++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeFunction.html#ga8b0c32e7322e5c6c1bf7eb95b0961707>+foreign import ccall unsafe "LLVMFunctionType" functionType' ::+  Ptr Type -> Ptr (Ptr Type) -> CUInt -> LLVMBool -> IO (Ptr Type)++functionType :: Ptr Type -> (CUInt, Ptr (Ptr Type)) -> LLVMBool -> IO (Ptr Type)+functionType rt (n, ats) va = functionType' rt ats n va++newtype AddrSpace = AddrSpace CUInt+-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeSequential.html#ga299fe6147083678d0494b1b875f542fae>+foreign import ccall unsafe "LLVMPointerType" pointerType ::+  Ptr Type -> AddrSpace -> IO (Ptr Type)++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeSequential.html#ga124b162b69b5def41dde2fda3668cbd9>+foreign import ccall unsafe "LLVMGetPointerAddressSpace" getPointerAddressSpace ::+  Ptr Type -> IO AddrSpace++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeSequential.html#ga5ec731adf74fb40bc3b401956d0c6ff2>+foreign import ccall unsafe "LLVMVectorType" vectorType ::+  Ptr Type -> CUInt -> IO (Ptr Type)++-- | what <http://llvm.org/doxygen/group__LLVMCCoreTypeSequential.html#gabd1666e080f693e1af0b4018005cd927>+-- | would be if it supported 64-bit array sizes, as the C++ type does.+foreign import ccall unsafe "LLVM_Hs_ArrayType" arrayType ::+  Ptr Type -> Word64 -> IO (Ptr Type)++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeStruct.html#gaff2af74740a22f7d18701f0d8c3e5a6f>+foreign import ccall unsafe "LLVMStructTypeInContext" structTypeInContext' ::+  Ptr Context -> Ptr (Ptr Type) -> CUInt -> LLVMBool -> IO (Ptr Type)++structTypeInContext :: Ptr Context -> (CUInt, Ptr (Ptr Type)) -> LLVMBool -> IO (Ptr Type)+structTypeInContext ctx (n, ts) p = structTypeInContext' ctx ts n p++foreign import ccall unsafe "LLVM_Hs_StructCreateNamed" structCreateNamed ::+  Ptr Context -> CString -> IO (Ptr Type)++foreign import ccall unsafe "LLVMGetStructName" getStructName ::+  Ptr Type -> IO CString++foreign import ccall unsafe "LLVM_Hs_StructIsLiteral" structIsLiteral ::+  Ptr Type -> IO LLVMBool++foreign import ccall unsafe "LLVM_Hs_StructIsOpaque" structIsOpaque ::+  Ptr Type -> IO LLVMBool++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeStruct.html#ga3e940e660375ae0cbdde81c0d8ec91e3>+foreign import ccall unsafe "LLVMIsPackedStruct" isPackedStruct ::+  Ptr Type -> IO LLVMBool++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeStruct.html#gaf32e6d6bcec38b786efbef689b0dddf7>+foreign import ccall unsafe "LLVMCountStructElementTypes" countStructElementTypes ::+  Ptr Type -> IO CUInt++foreign import ccall unsafe "LLVMGetStructElementTypes" getStructElementTypes ::+  Ptr Type -> Ptr (Ptr Type) -> IO ()++foreign import ccall unsafe "LLVMStructSetBody" structSetBody' ::+  Ptr Type -> Ptr (Ptr Type) -> CUInt -> LLVMBool -> IO ()++structSetBody :: Ptr Type -> (CUInt, Ptr (Ptr Type)) -> LLVMBool -> IO ()+structSetBody s (n,ts) p = structSetBody' s ts n p++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeSequential.html#gafb88a5ebd2a8062e105854910dc7ca17>+foreign import ccall unsafe "LLVMGetVectorSize" getVectorSize ::+  Ptr Type -> IO CUInt++-- | what <http://llvm.org/doxygen/group__LLVMCCoreTypeSequential.html#ga02dc08041a12265cb700ee469497df63>+-- | would be if it supported 64 bit lengths+foreign import ccall unsafe "LLVM_Hs_GetArrayLength" getArrayLength ::+  Ptr Type -> IO Word64++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeOther.html#ga1c78ca6d7bf279330b9195fa52f23828>+foreign import ccall unsafe "LLVMVoidTypeInContext" voidTypeInContext ::+  Ptr Context -> IO (Ptr Type)++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeFloat.html#ga3a5332a1d075602bccad7576d1a8e36f>+foreign import ccall unsafe "LLVMHalfTypeInContext" halfTypeInContext ::+  Ptr Context -> IO (Ptr Type)++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeFloat.html#ga529c83a8a5461e5beac19eb867216e3c>+foreign import ccall unsafe "LLVMFloatTypeInContext" floatTypeInContext ::+  Ptr Context -> IO (Ptr Type)++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeFloat.html#ga200527010747eab31b73d3e3f6d94935>+foreign import ccall unsafe "LLVMDoubleTypeInContext" doubleTypeInContext ::+  Ptr Context -> IO (Ptr Type)++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeFloat.html#ga24f77b84b625ed3dd516b52480606093>+foreign import ccall unsafe "LLVMX86FP80TypeInContext" x86FP80TypeInContext ::+  Ptr Context -> IO (Ptr Type)++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeFloat.html#ga1c02fb08f9ae12a719ed42099d42ccd8>+foreign import ccall unsafe "LLVMFP128TypeInContext" fP128TypeInContext ::+  Ptr Context -> IO (Ptr Type)++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeFloat.html#gac2491184fc3d8631c7b264c067f2f761>+foreign import ccall unsafe "LLVMPPCFP128TypeInContext" ppcFP128TypeInContext ::+  Ptr Context -> IO (Ptr Type)++-- | <http://llvm.org/doxygen/classllvm_1_1Type.html#a28fdf240b8220065bc60d6d1b1a2f174>+foreign import ccall unsafe "LLVM_Hs_MetadataTypeInContext" metadataTypeInContext ::+  Ptr Context -> IO (Ptr Type)++-- | <http://llvm.org/docs/doxygen/html/Core_8cpp.html#a5d3702e198e2373db7e31bb18879efc3>+foreign import ccall unsafe "LLVM_Hs_TokenTypeInContext" tokenTypeInContext ::+  Ptr Context -> IO (Ptr Type)
+ src/LLVM/Internal/FFI/TypeC.cpp view
@@ -0,0 +1,42 @@+#define __STDC_LIMIT_MACROS+#include "llvm-c/Core.h"+#include "llvm/IR/DerivedTypes.h"+#include "llvm/IR/LLVMContext.h"+#include "llvm/IR/Type.h"++using namespace llvm;++extern "C" {++LLVMTypeRef LLVM_Hs_StructCreateNamed(LLVMContextRef C, const char *Name) {+    if (Name) {+        return wrap(StructType::create(*unwrap(C), Name));+    } else {+        return wrap(StructType::create(*unwrap(C)));+    }+}++LLVMBool LLVM_Hs_StructIsLiteral(LLVMTypeRef t) {+    return unwrap<StructType>(t)->isLiteral();+}++LLVMBool LLVM_Hs_StructIsOpaque(LLVMTypeRef t) {+    return unwrap<StructType>(t)->isOpaque();+}++LLVMTypeRef LLVM_Hs_ArrayType(LLVMTypeRef ElementType, uint64_t ElementCount) {+    return wrap(ArrayType::get(unwrap(ElementType), ElementCount));+}++uint64_t LLVM_Hs_GetArrayLength(LLVMTypeRef ArrayTy) {+    return unwrap<ArrayType>(ArrayTy)->getNumElements();+}++LLVMTypeRef LLVM_Hs_MetadataTypeInContext(LLVMContextRef C) {+    return wrap(Type::getMetadataTy(*unwrap(C)));+}++LLVMTypeRef LLVM_Hs_TokenTypeInContext(LLVMContextRef C) {+    return wrap(Type::getTokenTy(*unwrap(C)));+}+}
+ src/LLVM/Internal/FFI/User.hs view
@@ -0,0 +1,38 @@+{-# LANGUAGE+  ForeignFunctionInterface,+  MultiParamTypeClasses,+  UndecidableInstances+  #-}+-- | FFI functions for handling the LLVM User class+module LLVM.Internal.FFI.User where++import LLVM.Prelude++import Foreign.Ptr+import Foreign.C++import LLVM.Internal.FFI.PtrHierarchy++-- | a blind type to correspond to llvm::Use+data Use++-- | test if a 'Value' is a 'User'+foreign import ccall unsafe "LLVMIsAUser" isAUser ::+    Ptr Value -> IO (Ptr User)++-- | <http://llvm.org/doxygen/group__LLVMCCoreValueUses.html#ga66a226d3d06ffada5c929656f4d97d35>+foreign import ccall unsafe "LLVMGetFirstUse" getFirstUse ::+    Ptr User -> IO (Ptr Use)++-- | <http://llvm.org/doxygen/group__LLVMCCoreValueUses.html#ga6ea72661bcca2b77bea57173317ec942>+foreign import ccall unsafe "LLVMGetNextUse" getNextUse ::+    Ptr Use -> IO (Ptr Use)++-- | <http://llvm.org/doxygen/group__LLVMCCoreValueUser.html#ga2ad633a6afc7906f1afe329f244240f6>+foreign import ccall unsafe "LLVMGetNumOperands" getNumOperands ::+    Ptr User -> IO CUInt++-- | <http://llvm.org/doxygen/group__LLVMCCoreValueUser.html#ga799d58a361054323cb457945071cbfdb>+foreign import ccall unsafe "LLVMGetOperand" getOperand ::+    Ptr User -> CUInt -> IO (Ptr Value)+
+ src/LLVM/Internal/FFI/Value.h view
@@ -0,0 +1,32 @@+#ifndef __LLVM_INTERNAL_FFI__VALUE__H__+#define __LLVM_INTERNAL_FFI__VALUE__H__++#define LLVM_HS_FOR_EACH_VALUE_SUBCLASS(macro) \+	macro(Argument) \+	macro(BasicBlock) \+	macro(Function) \+	macro(GlobalAlias) \+	macro(GlobalVariable) \+	macro(UndefValue) \+	macro(BlockAddress) \+	macro(ConstantExpr) \+	macro(ConstantAggregateZero) \+	macro(ConstantDataArray) \+	macro(ConstantDataVector) \+	macro(ConstantInt) \+	macro(ConstantFP) \+	macro(ConstantArray) \+	macro(ConstantStruct) \+	macro(ConstantTokenNone) \+	macro(ConstantVector) \+	macro(ConstantPointerNull) \+	macro(InlineAsm) \+	macro(Instruction)++typedef enum {+#define ENUM_CASE(class) LLVM ## class ## SubclassId,+LLVM_HS_FOR_EACH_VALUE_SUBCLASS(ENUM_CASE)+#undef ENUM_CASE+} LLVMValueSubclassId;++#endif
+ src/LLVM/Internal/FFI/Value.hs view
@@ -0,0 +1,41 @@+{-# LANGUAGE+  ForeignFunctionInterface,+  MultiParamTypeClasses,+  UndecidableInstances+  #-}+-- | FFI functions for handling the LLVM Value class+module LLVM.Internal.FFI.Value where++import LLVM.Prelude++import Foreign.Ptr+import Foreign.C++import LLVM.Internal.FFI.LLVMCTypes+import LLVM.Internal.FFI.PtrHierarchy++-- | <http://llvm.org/doxygen/group__LLVMCCoreValueGeneral.html#ga12179f46b79de8436852a4189d4451e0>+foreign import ccall unsafe "LLVMTypeOf" typeOf ::+  Ptr Value -> IO (Ptr Type)++-- | <http://llvm.org/doxygen/group__LLVMCCoreValueGeneral.html#ga70948786725c43968d15225dd584e5a9>+foreign import ccall unsafe "LLVMGetValueName" getValueName ::+  Ptr Value -> IO CString++-- | <http://llvm.org/doxygen/group__LLVMCCoreValueGeneral.html#gac1f61f74d83d218d4943c018e8fd8d13>+foreign import ccall unsafe "LLVMSetValueName" setValueName ::+  Ptr Value -> CString -> IO ()++-- | This function exposes the ID returned by llvm::Value::getValueID()+-- | <http://llvm.org/doxygen/classllvm_1_1Value.html#a2983b7b4998ef5b9f51b18c01588af3c>. +foreign import ccall unsafe "LLVM_Hs_GetValueSubclassId" getValueSubclassId ::+  Ptr Value -> IO ValueSubclassId++foreign import ccall unsafe "LLVMReplaceAllUsesWith" replaceAllUsesWith ::+  Ptr Value -> Ptr Value -> IO ()++foreign import ccall unsafe "LLVM_Hs_CreateArgument" createArgument ::+  Ptr Type -> CString -> IO (Ptr Value)++foreign import ccall unsafe "LLVMDumpValue" dumpValue ::+  Ptr Value -> IO ()
+ src/LLVM/Internal/FFI/ValueC.cpp view
@@ -0,0 +1,30 @@+#define __STDC_LIMIT_MACROS+#include "llvm-c/Core.h"+#include "llvm/IR/Type.h"+#include "llvm/IR/DerivedTypes.h"+#include "llvm/IR/Value.h"+#include "llvm/IR/Argument.h"+#include "LLVM/Internal/FFI/Value.h"++using namespace llvm;++extern "C" {++LLVMValueSubclassId LLVM_Hs_GetValueSubclassId(LLVMValueRef v) {+	switch(unwrap(v)->getValueID()) {+#define VALUE_SUBCLASS_ID_CASE(class) case Value::class ## Val: return LLVM ## class ## SubclassId;+LLVM_HS_FOR_EACH_VALUE_SUBCLASS(VALUE_SUBCLASS_ID_CASE)+#undef VALUE_SUBCLASS_ID_CASE+	default: break;+	}+	return LLVMValueSubclassId(0);+}++LLVMValueRef LLVM_Hs_CreateArgument(+	LLVMTypeRef t,+	const char *name+) {+	return wrap(new Argument(unwrap(t), name));+}++}
+ src/LLVM/Internal/FastMathFlags.hs view
@@ -0,0 +1,51 @@+{-# LANGUAGE +  MultiParamTypeClasses+  #-}+module LLVM.Internal.FastMathFlags where++import LLVM.Prelude++import Control.Monad.Trans+import Control.Monad.AnyCont+import Control.Monad.State+import Control.Exception++import Data.Bits++import qualified LLVM.Internal.FFI.Builder as FFI+import qualified LLVM.Internal.FFI.LLVMCTypes as FFI++import LLVM.Internal.Coding+import LLVM.Internal.EncodeAST++import qualified LLVM.AST as A++instance EncodeM IO A.FastMathFlags FFI.FastMathFlags where+  encodeM A.NoFastMathFlags = return 0+  encodeM A.UnsafeAlgebra = return FFI.fastMathFlagsUnsafeAlgebra+  encodeM f = return $ foldr1 (.|.) [ +               if a f then b else 0+               | (a,b) <- [+                (A.noNaNs, FFI.fastMathFlagsNoNaNs),+                (A.noInfs, FFI.fastMathFlagsNoInfs),+                (A.noSignedZeros, FFI.fastMathFlagsNoSignedZeros),+                (A.allowReciprocal, FFI.fastMathFlagsAllowReciprocal)+               ] +              ]++instance EncodeM EncodeAST A.FastMathFlags () where+  encodeM f = do +    f <- liftIO $ encodeM f+    builder <- gets encodeStateBuilder+    anyContToM $ bracket (FFI.setFastMathFlags builder f) (\() -> FFI.setFastMathFlags builder 0)++instance Monad m => DecodeM m A.FastMathFlags FFI.FastMathFlags where+  decodeM 0 = return A.NoFastMathFlags+  decodeM f | FFI.fastMathFlagsUnsafeAlgebra .&. f /= 0 = return A.UnsafeAlgebra+  decodeM f = return A.FastMathFlags {+                A.noNaNs = FFI.fastMathFlagsNoNaNs .&. f /= 0,+                A.noInfs = FFI.fastMathFlagsNoInfs .&. f /= 0,+                A.noSignedZeros = FFI.fastMathFlagsNoSignedZeros .&. f /= 0,+                A.allowReciprocal = FFI.fastMathFlagsAllowReciprocal .&. f /= 0+              }+
+ src/LLVM/Internal/FloatingPointPredicate.hs view
@@ -0,0 +1,29 @@+{-# LANGUAGE+  MultiParamTypeClasses,+  TemplateHaskell+  #-}+module LLVM.Internal.FloatingPointPredicate where++import LLVM.Internal.Coding++import qualified LLVM.Internal.FFI.LLVMCTypes as FFI+import qualified LLVM.AST.FloatingPointPredicate as A.FPPred++genCodingInstance [t| A.FPPred.FloatingPointPredicate |] ''FFI.FCmpPredicate [+  (FFI.fCmpPredFalse, A.FPPred.False),+  (FFI.fCmpPredOEQ, A.FPPred.OEQ),+  (FFI.fCmpPredOGT, A.FPPred.OGT),+  (FFI.fCmpPredOGE, A.FPPred.OGE),+  (FFI.fCmpPredOLT, A.FPPred.OLT),+  (FFI.fCmpPredOLE, A.FPPred.OLE),+  (FFI.fCmpPredONE, A.FPPred.ONE),+  (FFI.fCmpPredORD, A.FPPred.ORD),+  (FFI.fCmpPredUNO, A.FPPred.UNO),+  (FFI.fCmpPredUEQ, A.FPPred.UEQ),+  (FFI.fCmpPredUGT, A.FPPred.UGT),+  (FFI.fCmpPredUGE, A.FPPred.UGE),+  (FFI.fCmpPredULT, A.FPPred.ULT),+  (FFI.fCmpPredULE, A.FPPred.ULE),+  (FFI.fCmpPredUNE, A.FPPred.UNE),+  (FFI.fcmpPredTrue, A.FPPred.True)+ ]
+ src/LLVM/Internal/Function.hs view
@@ -0,0 +1,70 @@+module LLVM.Internal.Function where++import LLVM.Prelude++import Control.Monad.Trans+import Control.Monad.AnyCont++import Foreign.C (CUInt)+import Foreign.Ptr  ++import Data.Map (Map)+import qualified Data.Map as Map++import qualified LLVM.Internal.FFI.Function as FFI+import qualified LLVM.Internal.FFI.PtrHierarchy as FFI++import LLVM.Internal.DecodeAST+import LLVM.Internal.EncodeAST+import LLVM.Internal.Value+import LLVM.Internal.Coding+import LLVM.Internal.Constant ()+import LLVM.Internal.Attribute++import qualified LLVM.AST as A+import qualified LLVM.AST.Constant as A+import qualified LLVM.AST.ParameterAttribute as A.PA  ++getMixedAttributeSet :: Ptr FFI.Function -> DecodeAST MixedAttributeSet+getMixedAttributeSet = decodeM <=< liftIO . FFI.getMixedAttributeSet++setFunctionAttributes :: Ptr FFI.Function -> MixedAttributeSet -> EncodeAST ()+setFunctionAttributes f = (liftIO . FFI.setMixedAttributeSet f) <=< encodeM++getParameters :: Ptr FFI.Function -> Map CUInt [A.PA.ParameterAttribute] -> DecodeAST [A.Parameter]+getParameters f attrs = scopeAnyCont $ do+  n <- liftIO (FFI.countParams f)+  ps <- allocaArray n+  liftIO $ FFI.getParams f ps+  params <- peekArray n ps+  forM (zip params [0..]) $ \(param, i) -> +    return A.Parameter +       `ap` typeOf param+       `ap` getLocalName param+       `ap` (return $ Map.findWithDefault [] i attrs)+  +getGC :: Ptr FFI.Function -> DecodeAST (Maybe String)+getGC f = scopeAnyCont $ decodeM =<< liftIO (FFI.getGC f)++setGC :: Ptr FFI.Function -> Maybe String -> EncodeAST ()+setGC f gc = scopeAnyCont $ liftIO . FFI.setGC f =<< encodeM gc ++getPrefixData :: Ptr FFI.Function -> DecodeAST (Maybe A.Constant)+getPrefixData f = do+  has <- decodeM =<< (liftIO $ FFI.hasPrefixData f)+  if has+   then decodeM =<< (liftIO $ FFI.getPrefixData f)+   else return Nothing++setPrefixData :: Ptr FFI.Function -> Maybe A.Constant -> EncodeAST ()+setPrefixData f = maybe (return ()) (liftIO . FFI.setPrefixData f <=< encodeM)++getPersonalityFn :: Ptr FFI.Function -> DecodeAST (Maybe A.Constant)+getPersonalityFn f = do+  has <- decodeM =<< liftIO (FFI.hasPersonalityFn f)+  if has+     then decodeM =<< liftIO (FFI.getPersonalityFn f)+     else pure Nothing++setPersonalityFn :: Ptr FFI.Function -> Maybe A.Constant -> EncodeAST ()+setPersonalityFn f personality = (liftIO . FFI.setPersonalityFn f =<< encodeM personality)
+ src/LLVM/Internal/Global.hs view
@@ -0,0 +1,146 @@+{-# LANGUAGE+  TemplateHaskell,+  MultiParamTypeClasses+  #-}+module LLVM.Internal.Global where++import LLVM.Prelude++import Control.Monad.State+import Control.Monad.AnyCont+import Foreign.Ptr+import qualified Data.Map as Map++import qualified LLVM.Internal.FFI.PtrHierarchy as FFI+import qualified LLVM.Internal.FFI.LLVMCTypes as FFI+import qualified LLVM.Internal.FFI.GlobalValue as FFI++import LLVM.Internal.Coding+import LLVM.Internal.DecodeAST+import LLVM.Internal.EncodeAST++import qualified LLVM.AST.Linkage as A.L+import qualified LLVM.AST.Visibility as A.V+import qualified LLVM.AST.COMDAT as A.COMDAT+import qualified LLVM.AST.DLL as A.DLL+import qualified LLVM.AST.ThreadLocalStorage as A.TLS+import qualified LLVM.AST.Global as A.G++genCodingInstance [t| A.L.Linkage |] ''FFI.Linkage [+  (FFI.linkageExternal, A.L.External),+  (FFI.linkageAvailableExternally, A.L.AvailableExternally),+  (FFI.linkageLinkOnceAny, A.L.LinkOnce),+  (FFI.linkageLinkOnceODR, A.L.LinkOnceODR),+  (FFI.linkageWeakAny, A.L.Weak),+  (FFI.linkageWeakODR, A.L.WeakODR),+  (FFI.linkageAppending, A.L.Appending),+  (FFI.linkageInternal, A.L.Internal),+  (FFI.linkagePrivate, A.L.Private),+  (FFI.linkageExternalWeak, A.L.ExternWeak),+  (FFI.linkageCommon, A.L.Common)+ ]++getLinkage :: FFI.DescendentOf FFI.GlobalValue v => Ptr v -> DecodeAST A.L.Linkage+getLinkage g = liftIO $ decodeM =<< FFI.getLinkage (FFI.upCast g)++setLinkage :: FFI.DescendentOf FFI.GlobalValue v => Ptr v -> A.L.Linkage -> EncodeAST ()+setLinkage g l = liftIO . FFI.setLinkage (FFI.upCast g) =<< encodeM l+                                                                       +genCodingInstance [t| A.V.Visibility |] ''FFI.Visibility [+  (FFI.visibilityDefault, A.V.Default),+  (FFI.visibilityHidden, A.V.Hidden),+  (FFI.visibilityProtected, A.V.Protected)+ ]++getVisibility :: FFI.DescendentOf FFI.GlobalValue v => Ptr v -> DecodeAST A.V.Visibility+getVisibility g = liftIO $ decodeM =<< FFI.getVisibility (FFI.upCast g)++setVisibility :: FFI.DescendentOf FFI.GlobalValue v => Ptr v -> A.V.Visibility -> EncodeAST ()+setVisibility g v = liftIO . FFI.setVisibility (FFI.upCast g) =<< encodeM v++genCodingInstance [t| Maybe A.DLL.StorageClass |] ''FFI.DLLStorageClass [+  (FFI.dllStorageClassDefault, Nothing),+  (FFI.dllStorageClassDLLImport, Just A.DLL.Import),+  (FFI.dllStorageClassDLLExport, Just A.DLL.Export)+ ]++getDLLStorageClass :: FFI.DescendentOf FFI.GlobalValue v => Ptr v -> DecodeAST (Maybe A.DLL.StorageClass)+getDLLStorageClass g = liftIO $ decodeM =<< FFI.getDLLStorageClass (FFI.upCast g)++setDLLStorageClass :: FFI.DescendentOf FFI.GlobalValue v => Ptr v -> Maybe A.DLL.StorageClass -> EncodeAST ()+setDLLStorageClass g sc = liftIO . FFI.setDLLStorageClass (FFI.upCast g) =<< encodeM sc++getSection :: FFI.DescendentOf FFI.GlobalValue v => Ptr v -> DecodeAST (Maybe String)+getSection g = do+  sectionLengthPtr <- alloca+  sectionNamePtr <- liftIO $ FFI.getSection (FFI.upCast g) sectionLengthPtr+  if sectionNamePtr == nullPtr then+    return Nothing+    else+      do sectionLength <- peek sectionLengthPtr+         sectionName <- decodeM (sectionNamePtr, sectionLength)+         return (Just sectionName)++setSection :: FFI.DescendentOf FFI.GlobalValue v => Ptr v -> Maybe String -> EncodeAST ()+setSection g s = scopeAnyCont $ do+  s <- encodeM (maybe "" id s)+  liftIO $ FFI.setSection (FFI.upCast g) s++genCodingInstance [t| A.COMDAT.SelectionKind |] ''FFI.COMDATSelectionKind [+  (FFI.comdatSelectionKindAny, A.COMDAT.Any),+  (FFI.comdatSelectionKindExactMatch, A.COMDAT.ExactMatch),+  (FFI.comdatSelectionKindLargest, A.COMDAT.Largest),+  (FFI.comdatSelectionKindNoDuplicates, A.COMDAT.NoDuplicates),+  (FFI.comdatSelectionKindSameSize, A.COMDAT.SameSize)+ ]++instance DecodeM DecodeAST (String, A.COMDAT.SelectionKind) (Ptr FFI.COMDAT) where+  decodeM c = return (,)+              `ap` (decodeM $ FFI.getCOMDATName c)+              `ap` (decodeM =<< liftIO (FFI.getCOMDATSelectionKind c))++getCOMDATName :: FFI.DescendentOf FFI.GlobalValue v => Ptr v -> DecodeAST (Maybe String)+getCOMDATName g = do+  c <- liftIO $ FFI.getCOMDAT (FFI.upCast g)+  if c == nullPtr+   then return Nothing+   else do+     cds <- gets comdats+     liftM Just $ case Map.lookup c cds of+       Just (name, _) -> return name+       Nothing -> do+          cd@(name, _) <- decodeM c+          modify $ \s -> s { comdats = Map.insert c cd cds }+          return name++setCOMDAT :: FFI.DescendentOf FFI.GlobalObject v => Ptr v -> Maybe String -> EncodeAST ()+setCOMDAT _ Nothing = return ()+setCOMDAT g (Just name) = do+  cd <- referCOMDAT name+  liftIO $ FFI.setCOMDAT (FFI.upCast g) cd++setAlignment :: FFI.DescendentOf FFI.GlobalValue v => Ptr v -> Word32 -> EncodeAST ()+setAlignment g i = liftIO $ FFI.setAlignment (FFI.upCast g) (fromIntegral i)++getAlignment :: FFI.DescendentOf FFI.GlobalValue v => Ptr v -> DecodeAST Word32+getAlignment g = liftIO $ fromIntegral <$> FFI.getAlignment (FFI.upCast g)++genCodingInstance [t| Maybe A.TLS.Model |] ''FFI.ThreadLocalMode [+  (FFI.threadLocalModeNotThreadLocal, Nothing),+  (FFI.threadLocalModeGeneralDynamicTLSModel, Just A.TLS.GeneralDynamic),+  (FFI.threadLocalModeLocalDynamicTLSModel, Just A.TLS.LocalDynamic),+  (FFI.threadLocalModeInitialExecTLSModel, Just A.TLS.InitialExec),+  (FFI.threadLocalModeLocalExecTLSModel, Just A.TLS.LocalExec)+ ]++getThreadLocalMode :: FFI.DescendentOf FFI.GlobalValue v => Ptr v -> DecodeAST (Maybe A.TLS.Model)+getThreadLocalMode g = liftIO $ decodeM =<< FFI.getThreadLocalMode (FFI.upCast g)++setThreadLocalMode :: FFI.DescendentOf FFI.GlobalValue v => Ptr v -> Maybe A.TLS.Model -> EncodeAST ()+setThreadLocalMode g m = liftIO . FFI.setThreadLocalMode (FFI.upCast g) =<< encodeM m++genCodingInstance [t| Maybe A.G.UnnamedAddr |] ''FFI.UnnamedAddr [+  (FFI.unnamedAddrNone, Nothing),+  (FFI.unnamedAddrLocal, Just A.G.LocalAddr),+  (FFI.unnamedAddrGlobal, Just A.G.GlobalAddr)+ ]
+ src/LLVM/Internal/Inject.hs view
@@ -0,0 +1,11 @@+{-# LANGUAGE MultiParamTypeClasses #-}+module LLVM.Internal.Inject where++import LLVM.Prelude++class Inject a b where+  inject :: a -> b++instance Inject a a where+  inject = id+
+ src/LLVM/Internal/InlineAssembly.hs view
@@ -0,0 +1,68 @@+{-# LANGUAGE+  TemplateHaskell,+  MultiParamTypeClasses+  #-}+module LLVM.Internal.InlineAssembly where+ +import LLVM.Prelude++import Control.Monad.IO.Class++import Foreign.C+import Foreign.Ptr++import qualified LLVM.Internal.FFI.InlineAssembly as FFI+import qualified LLVM.Internal.FFI.LLVMCTypes as FFI+import qualified LLVM.Internal.FFI.Module as FFI+import qualified LLVM.Internal.FFI.PtrHierarchy as FFI++import qualified LLVM.AST as A (Definition(..))+import qualified LLVM.AST.InlineAssembly as A+import qualified LLVM.AST.Type as A++import LLVM.Internal.Coding +import LLVM.Internal.EncodeAST+import LLVM.Internal.DecodeAST+import LLVM.Internal.Value++genCodingInstance [t| A.Dialect |] ''FFI.AsmDialect [+   (FFI.asmDialectATT, A.ATTDialect),+   (FFI.asmDialectIntel, A.IntelDialect)+  ]++instance EncodeM EncodeAST A.InlineAssembly (Ptr FFI.InlineAsm) where+  encodeM (A.InlineAssembly {+             A.type' = t,+             A.assembly = assembly,+             A.constraints = constraints,+             A.hasSideEffects = hasSideEffects,+             A.alignStack = alignStack,+             A.dialect = dialect+           }) = do+    t <- encodeM t+    assembly <- encodeM assembly+    constraints <- encodeM constraints+    hasSideEffects <- encodeM hasSideEffects+    alignStack <- encodeM alignStack+    dialect <- encodeM dialect+    liftIO $ FFI.createInlineAsm t assembly constraints hasSideEffects alignStack dialect++instance DecodeM DecodeAST A.InlineAssembly (Ptr FFI.InlineAsm) where+  decodeM p = do+    return A.InlineAssembly+      `ap` (liftM (\(A.PointerType f _) -> f) (typeOf p))+      `ap` (decodeM =<< liftIO (FFI.getInlineAsmAssemblyString p))+      `ap` (decodeM =<< liftIO (FFI.getInlineAsmConstraintString p))+      `ap` (decodeM =<< liftIO (FFI.inlineAsmHasSideEffects p))+      `ap` (decodeM =<< liftIO (FFI.inlineAsmIsAlignStack p))+      `ap` (decodeM =<< liftIO (FFI.getInlineAsmDialect p))++instance DecodeM DecodeAST [A.Definition] (FFI.ModuleAsm CString) where+  decodeM (FFI.ModuleAsm s) = do+    s <- decodeM s+    let takeModIA "" = []+        takeModIA s =+          let (a,r) = break (== '\n') s+          in A.ModuleInlineAssembly a : takeModIA (dropWhile (== '\n') r)+    return $ takeModIA s+    
+ src/LLVM/Internal/Instruction.hs view
@@ -0,0 +1,607 @@+{-# LANGUAGE+  TemplateHaskell,+  QuasiQuotes,+  MultiParamTypeClasses,+  UndecidableInstances,+  ViewPatterns+  #-}+module LLVM.Internal.Instruction where++import LLVM.Prelude++import qualified Language.Haskell.TH as TH+import qualified Language.Haskell.TH.Quote as TH+import qualified LLVM.Internal.InstructionDefs as ID+import LLVM.Internal.InstructionDefs (instrP)++import Control.Monad.AnyCont+import Control.Monad.Error.Class+import Control.Monad.IO.Class+import Control.Monad.State (gets)++import Foreign.Ptr++import Control.Exception (assert)+import qualified Data.Map as Map+import qualified Data.List as List+import Data.List.NonEmpty (NonEmpty((:|)))+import qualified Data.List.NonEmpty as NonEmpty++import qualified LLVM.Internal.FFI.PtrHierarchy as FFI+import qualified LLVM.Internal.FFI.BinaryOperator as FFI+import qualified LLVM.Internal.FFI.Instruction as FFI+import qualified LLVM.Internal.FFI.Value as FFI+import qualified LLVM.Internal.FFI.User as FFI+import qualified LLVM.Internal.FFI.Builder as FFI+import qualified LLVM.Internal.FFI.Constant as FFI+import qualified LLVM.Internal.FFI.BasicBlock as FFI++import LLVM.Internal.Atomicity ()+import LLVM.Internal.Attribute+import LLVM.Internal.CallingConvention ()+import LLVM.Internal.Coding+import LLVM.Internal.DecodeAST+import LLVM.Internal.EncodeAST+import LLVM.Internal.FastMathFlags ()+import LLVM.Internal.Metadata ()+import LLVM.Internal.Operand ()+import LLVM.Internal.RMWOperation ()+import LLVM.Internal.TailCallKind ()+import LLVM.Internal.Type+import LLVM.Internal.Value++import qualified LLVM.AST as A+import qualified LLVM.AST.Constant as A.C++callInstAttributeSet :: Ptr FFI.Instruction -> DecodeAST MixedAttributeSet+callInstAttributeSet = decodeM <=< liftIO . FFI.getCallSiteAttributeSet++meta :: Ptr FFI.Instruction -> DecodeAST A.InstructionMetadata+meta i = do+  let getMetadata n = scopeAnyCont $ do+         ks <- allocaArray n+         ps <- allocaArray n+         n' <- liftIO $ FFI.getMetadata i ks ps n+         if (n' > n) +          then getMetadata n'+          else return zip `ap` decodeM (n', ks) `ap` decodeM (n', ps)+  getMetadata 4++setMD :: Ptr FFI.Instruction -> A.InstructionMetadata -> EncodeAST ()+setMD i md = forM_ md $ \(kindName, anode) -> do+               kindID <- encodeM kindName+               node <- encodeM anode+               liftIO $ FFI.setMetadata i kindID node++instance DecodeM DecodeAST A.Terminator (Ptr FFI.Instruction) where+  decodeM i = scopeAnyCont $ do+    n <- liftIO $ FFI.getInstructionDefOpcode i+    nOps <- liftIO $ FFI.getNumOperands (FFI.upCast i)+    md <- meta i+    let op n = decodeM =<< (liftIO $ FFI.getOperand (FFI.upCast i) n)+        successor n = decodeM =<< (liftIO $ FFI.isABasicBlock =<< FFI.getOperand (FFI.upCast i) n)+    case n of+      [instrP|Ret|] -> do+        returnOperand' <- if nOps == 0 then return Nothing else Just <$> op 0+        return $ A.Ret { A.returnOperand = returnOperand', A.metadata' = md }+      [instrP|Br|] -> do+        n <- liftIO $ FFI.getNumOperands (FFI.upCast i)+        case n of+          1 -> do+             dest <- successor 0+             return $ A.Br { A.dest = dest, A.metadata' = md }+          3 -> do+             condition <- op 0+             falseDest <- successor 1+             trueDest <- successor 2+             return $ A.CondBr {+               A.condition = condition,+               A.falseDest = falseDest, +               A.trueDest = trueDest,+               A.metadata' = md+             }+      [instrP|Switch|] -> do+        op0 <- op 0+        dd <- successor 1+        let nCases = (nOps - 2) `div` 2+        values <- allocaArray nCases+        dests <- allocaArray nCases+        liftIO $ FFI.getSwitchCases i values dests+        cases <- return zip `ap` peekArray nCases values `ap` peekArray nCases dests+        dests <- forM cases $ \(c, d) -> return (,) `ap` decodeM c `ap` decodeM d+        return A.Switch {+          A.operand0' = op0,+          A.defaultDest = dd,+          A.dests = dests,+          A.metadata' = md+        }+      [instrP|IndirectBr|] -> do+        op0 <- op 0+        let nDests = nOps - 1+        dests <- allocaArray nDests+        liftIO $ FFI.getIndirectBrDests i dests+        dests <- decodeM (nDests, dests)+        return A.IndirectBr {+           A.operand0' = op0,+           A.possibleDests = dests,+           A.metadata' = md+        }+      [instrP|Invoke|] -> do+        cc <- decodeM =<< liftIO (FFI.getCallSiteCallingConvention i)+        attrs <- callInstAttributeSet i+        fv <- liftIO $ FFI.getCallSiteCalledValue i+        f <- decodeM fv+        args <- forM [1..nOps-3] $ \j -> do+                  let pAttrs = Map.findWithDefault [] (j-1) (parameterAttributes attrs)+                  return (, pAttrs) `ap` op (j-1) +        rd <- successor (nOps - 2)+        ed <- successor (nOps - 1)+        return A.Invoke {+          A.callingConvention' = cc,+          A.returnAttributes' = returnAttributes attrs,+          A.function' = f,+          A.arguments' = args,+          A.functionAttributes' = functionAttributes attrs,+          A.returnDest = rd,+          A.exceptionDest = ed,+          A.metadata' = md+        }+      [instrP|Resume|] -> do+        op0 <- op 0+        return A.Resume {+          A.operand0' = op0,+          A.metadata' = md+        }+      [instrP|Unreachable|] -> do+        return A.Unreachable {+          A.metadata' = md+        }+      [instrP|CleanupRet|] -> do+        dest <- decodeM =<< liftIO (FFI.upCast <$> (FFI.getCleanupPad i) :: IO (Ptr FFI.Value))+        unwindDest <- decodeM =<< liftIO (FFI.getUnwindDest i)+        return A.CleanupRet {+          A.cleanupPad = dest,+          A.unwindDest = unwindDest,+          A.metadata' = md+        }+      [instrP|CatchRet|] -> do+        catchPad <- decodeM =<< liftIO (FFI.catchRetGetCatchPad i)+        successor <- decodeM =<< liftIO (FFI.catchRetGetSuccessor i)+        return A.CatchRet {+          A.catchPad = catchPad,+          A.successor = successor,+          A.metadata' = md+        }+      [instrP|CatchSwitch|] -> do+        parentPad' <- decodeM =<< liftIO (FFI.catchSwitchGetParentPad i)+        numHandlers <- liftIO (FFI.catchSwitchGetNumHandlers i)+        handlers <- assert (numHandlers > 0) $+          forM (0 :| [1..numHandlers - 1]) $ decodeM <=< liftIO . FFI.catchSwitchGetHandler i+        unwindDest <- decodeM =<< liftIO (FFI.catchSwitchGetUnwindDest i)+        return A.CatchSwitch {+          A.parentPad' = parentPad',+          A.catchHandlers = handlers,+          A.defaultUnwindDest = unwindDest,+          A.metadata' = md+        }++instance EncodeM EncodeAST A.Terminator (Ptr FFI.Instruction) where+  encodeM t = scopeAnyCont $ do+    builder <- gets encodeStateBuilder+    s <- encodeM ""+    t' <- case t of+      A.Ret { A.returnOperand = r } -> do+        rv <- maybe (return nullPtr) encodeM r+        FFI.upCast <$> do liftIO $ FFI.buildRet builder rv+      A.Br { A.dest = d } -> do+        db <- encodeM d+        FFI.upCast <$> do liftIO $ FFI.buildBr builder db+      A.CondBr { A.condition = c, A.trueDest = t, A.falseDest = f } -> do+        cv <- encodeM c+        tb <- encodeM t+        fb <- encodeM f+        FFI.upCast <$> do liftIO $ FFI.buildCondBr builder cv tb fb+      A.Switch {+        A.operand0' = op0,+        A.defaultDest = dd,+        A.dests = ds+      } -> do+        op0' <- encodeM op0+        dd' <- encodeM dd+        i <- liftIO $ FFI.buildSwitch builder op0' dd' (fromIntegral $ length ds)+        forM ds $ \(v,d) -> do+          v' <- encodeM v+          d' <- encodeM d+          liftIO $ FFI.addCase i v' d'+        return $ FFI.upCast i+      A.IndirectBr { +        A.operand0' = op0,+        A.possibleDests = dests+      } -> do+        op0' <- encodeM op0+        i <- liftIO $ FFI.buildIndirectBr builder op0' (fromIntegral $ length dests)+        forM dests $ \dest -> do+          d <- encodeM dest+          liftIO $ FFI.addDestination i d+        return $ FFI.upCast i+      A.Invoke {+        A.callingConvention' = cc,+        A.returnAttributes' = rAttrs,+        A.function' = fun,+        A.arguments' = args,+        A.functionAttributes' = fAttrs,+        A.returnDest = rd,+        A.exceptionDest = ed+      } -> do+        fv <- encodeM fun+        rb <- encodeM rd+        eb <- encodeM ed+        let (argvs, argAttrs) = unzip args+        (n, argvs) <- encodeM argvs+        i <- liftIO $ FFI.buildInvoke builder fv argvs n rb eb s+        attrs <- encodeM $ MixedAttributeSet fAttrs rAttrs (Map.fromList (zip [0..] argAttrs))+        liftIO $ FFI.setCallSiteAttributeSet i attrs+        cc <- encodeM cc+        liftIO $ FFI.setCallSiteCallingConvention i cc+        return $ FFI.upCast i+      A.Resume { +        A.operand0' = op0+      } -> do+        op0' <- encodeM op0+        i <- liftIO $ FFI.buildResume builder op0'+        return $ FFI.upCast i+      A.Unreachable {+      } -> do+        i <- liftIO $ FFI.buildUnreachable builder+        return $ FFI.upCast i+      A.CleanupRet {+        A.cleanupPad = cleanupPad,+        A.unwindDest = unwindDest+      } -> do+        cleanupPad' <- encodeM cleanupPad+        unwindDest' <- encodeM unwindDest+        liftIO $ FFI.buildCleanupRet builder cleanupPad' unwindDest'+      A.CatchRet {+        A.catchPad = catchPad,+        A.successor = successor+      } -> do+        catchPad' <- encodeM catchPad+        successor' <- encodeM successor+        liftIO $ FFI.buildCatchRet builder catchPad' successor'+      A.CatchSwitch {+        A.parentPad' = parentPad,+        A.catchHandlers = catchHandlers,+        A.defaultUnwindDest = unwindDest+      } -> do+        parentPad' <- encodeM parentPad+        unwindDest' <- encodeM unwindDest+        let numHandlers = fromIntegral (NonEmpty.length catchHandlers)+        i <- liftIO $ FFI.buildCatchSwitch builder parentPad' unwindDest' numHandlers+        mapM_ (liftIO . FFI.catchSwitchAddHandler i <=< encodeM) catchHandlers+        return i+    setMD t' (A.metadata' t)+    return t'      ++$(do+  let findInstrFields s = Map.findWithDefault (error $ "instruction missing from AST: " ++ show s) s+                          ID.astInstructionRecs++  [d|+    instance DecodeM DecodeAST A.Instruction (Ptr FFI.Instruction) where+      decodeM i = scopeAnyCont $ do+        t <- typeOf i+        nOps <- liftIO $ FFI.getNumOperands (FFI.upCast i)+        let op n = decodeM =<< (liftIO $ FFI.getOperand (FFI.upCast i) n)+            cop n = decodeM =<< (liftIO $ FFI.isAConstant =<< FFI.getOperand (FFI.upCast i) n)+            get_nsw b = liftIO $ decodeM =<< FFI.hasNoSignedWrap (FFI.upCast b)+            get_nuw b = liftIO $ decodeM =<< FFI.hasNoUnsignedWrap (FFI.upCast b)+            get_exact b = liftIO $ decodeM =<< FFI.isExact (FFI.upCast b)+            get_fastMathFlags b = liftIO $ decodeM =<< FFI.getFastMathFlags (FFI.upCast b)++        n <- liftIO $ FFI.getInstructionDefOpcode i+        $(+          let fieldDecoders :: String -> String -> ([String], TH.ExpQ)+              fieldDecoders lrn s = case s of+                "b" -> ([], [| liftIO $ FFI.isABinaryOperator (FFI.upCast i) |])+                "nsw" -> (["b"], [| get_nsw $(TH.dyn "b") |])+                "nuw" -> (["b"], [| get_nuw $(TH.dyn "b") |])+                "exact" -> (["b"], [| get_exact $(TH.dyn "b") |])+                "fastMathFlags" -> (["b"], [| get_fastMathFlags $(TH.dyn "b") |])+                "operand0" -> ([], [| op 0 |])+                "operand1" -> ([], [| op 1 |])+                "address" -> ([], case lrn of "Store" -> [| op 1 |]; _ -> [| op 0 |])+                "value" -> ([], case lrn of "Store" -> [| op 0 |]; _ -> [| op 1 |])+                "expected" -> ([], [| op 1 |])+                "replacement" -> ([], [| op 2 |])+                "condition'" -> ([], [| op 0 |])+                "trueValue" -> ([], [| op 1 |])+                "falseValue" -> ([], [| op 2 |])+                "argList" -> ([], [| op 0 |])+                "vector" -> ([], [| op 0 |])+                "element" -> ([], [| op 1 |])+                "index" -> ([], case lrn of "ExtractElement" -> [| op 1 |]; "InsertElement" -> [| op 2 |])+                "mask" -> ([], [| cop 2 |])+                "aggregate" -> ([], [| op 0 |])+                "metadata" -> ([], [| meta i |])+                "iPredicate" -> ([], [| decodeM =<< liftIO (FFI.getICmpPredicate i) |])+                "fpPredicate" -> ([], [| decodeM =<< liftIO (FFI.getFCmpPredicate i) |])+                "tailCallKind" -> ([], [| decodeM =<< liftIO (FFI.getTailCallKind i) |])+                "callingConvention" -> ([], [| decodeM =<< liftIO (FFI.getCallSiteCallingConvention i) |])+                "attrs" -> ([], [| callInstAttributeSet i |])+                "returnAttributes" -> (["attrs"], [| return $ returnAttributes $(TH.dyn "attrs") |])+                "f" -> ([], [| liftIO $ FFI.getCallSiteCalledValue i |])+                "function" -> (["f"], [| decodeM $(TH.dyn "f") |])+                "arguments" -> ([], [| forM [1..nOps-1] $ \j -> do+                                         let pAttrs = Map.findWithDefault [] (j-1) (parameterAttributes $(TH.dyn "attrs"))+                                         p <- op (j-1)+                                         return (p, pAttrs) |])+                "clauses" -> +                  ([], [|do+                          nClauses <- liftIO $ FFI.getNumClauses i+                          -- We need to convert nClauses to a signed+                          -- value before subtracting+                          forM [0..fromIntegral nClauses - (1 :: Int)] $ \j -> do+                          v <- liftIO $ FFI.getClause i (fromIntegral j)+                          c <- decodeM v+                          t <- typeOf v+                          return $ case t of { A.ArrayType _ _ -> A.Filter; _ -> A.Catch} $ c |])+                "functionAttributes" -> (["attrs"], [| return $ functionAttributes $(TH.dyn "attrs") |])+                "type'" -> ([], [| return t |])+                "incomingValues" ->+                    ([], [| do+                            n <- liftIO $ FFI.countIncoming i+                            forM [0..n-1] $ \m -> do+                              iv <- decodeM =<< (liftIO $ FFI.getIncomingValue i m)+                              ib <- decodeM =<< (liftIO $ FFI.getIncomingBlock i m)+                              return (iv,ib) |])+                "allocatedType" -> ([], [| decodeM =<< liftIO (FFI.getAllocatedType i) |])+                "numElements" -> +                    ([], [| do+                            n <- decodeM =<< (liftIO $ FFI.getAllocaNumElements i)+                            return $ case n of+                              A.ConstantOperand (A.C.Int { A.C.integerValue = 1 }) -> Nothing+                              _ -> Just n+                              |])                +                "alignment" -> ([], [| decodeM =<< liftIO (FFI.getInstrAlignment i) |])+                "maybeAtomicity" -> ([], [| decodeM =<< liftIO (FFI.getAtomicity i) |])+                "atomicity" -> ([], [| decodeM =<< liftIO (FFI.getAtomicity i) |])+                "volatile" -> ([], [| decodeM =<< liftIO (FFI.getVolatile i) |])+                "inBounds" -> ([], [| decodeM =<< liftIO (FFI.getInBounds (FFI.upCast i)) |])+                "failureMemoryOrdering" -> ([], [| decodeM =<< liftIO (FFI.getFailureAtomicOrdering i) |])+                "indices" -> ([], [| mapM op [1..nOps-1] |])+                "indices'" ->+                  ([], [| do+                          n <- liftIO $ FFI.countInstStructureIndices i+                          a <- allocaArray n+                          liftIO $ FFI.getInstStructureIndices i a+                          decodeM (n, a) |])+                "rmwOperation" -> ([], [| decodeM =<< liftIO (FFI.getAtomicRMWBinOp i) |])+                "cleanup" -> ([], [| decodeM =<< liftIO (FFI.isCleanup i) |])+                "parentPad" -> ([], [| decodeM =<< liftIO (FFI.getParentPad i) |])+                "catchSwitch" -> ([], [| decodeM =<< liftIO (FFI.getParentPad i) |])+                "args" -> ([], [| do numArgs <- liftIO (FFI.getNumArgOperands i)+                                     if (numArgs == 0)+                                       then return []+                                       else forM [0..numArgs-1] $ \op ->+                                              decodeM =<< liftIO (FFI.getArgOperand i op) |])+                _ -> ([], [| error $ "unrecognized instruction field or depenency thereof: " ++ show s |])+          in+          TH.caseE [| n |] [+            TH.match opcodeP (TH.normalB (TH.doE handlerBody)) []+            | (lrn, iDef) <- Map.toList ID.instructionDefs,+              ID.instructionKind iDef /= ID.Terminator,+              let opcodeP = TH.dataToPatQ (const Nothing) (ID.cppOpcode iDef)+                  handlerBody = +                    let TH.RecC fullName fields = findInstrFields lrn+                        (fieldNames,_,_) = unzip3 fields+                        allNames ns = List.nub $ [ d | n <- ns, d <- allNames . fst . fieldDecoders lrn $ n ] ++ ns+                    in+                      [ +                       TH.bindS (TH.varP (TH.mkName n)) (snd . fieldDecoders lrn $ n)+                       | n <- allNames . map TH.nameBase $ fieldNames +                      ] ++ [ +                       TH.noBindS [| +                        return $(TH.recConE +                                 fullName+                                 [ (f,) <$> (TH.varE . TH.mkName . TH.nameBase $ f) | f <- fieldNames ])+                        |]+                      ]+                ]+         )++    instance EncodeM EncodeAST A.Instruction (Ptr FFI.Instruction, EncodeAST ()) where+      encodeM o = scopeAnyCont $ do+        builder <- gets encodeStateBuilder+        let return' i = return (FFI.upCast i, return ())+        s <- encodeM ""+        (inst, act) <- case o of+          A.ICmp { +            A.iPredicate = pred,+            A.operand0 = op0,+            A.operand1 = op1+          } -> do+            op0' <- encodeM op0+            op1' <- encodeM op1+            pred <- encodeM pred+            i <- liftIO $ FFI.buildICmp builder pred op0' op1' s+            return' i+          A.FCmp {+            A.fpPredicate = pred,+            A.operand0 = op0,+            A.operand1 = op1+          } -> do+            op0' <- encodeM op0+            op1' <- encodeM op1+            pred <- encodeM pred+            i <- liftIO $ FFI.buildFCmp builder pred op0' op1' s+            return' i+          A.Phi { A.type' = t, A.incomingValues = ivs } -> do+             t' <- encodeM t+             i <- liftIO $ FFI.buildPhi builder t' s+             return (+               FFI.upCast i,+               do+                 let (ivs3, bs3) = unzip ivs+                 ivs3' <- encodeM ivs3+                 bs3' <- encodeM bs3+                 liftIO $ FFI.addIncoming i ivs3' bs3'+               )+          A.Call {+            A.tailCallKind = tck,+            A.callingConvention = cc,+            A.returnAttributes = rAttrs,+            A.function = f,+            A.arguments = args,+            A.functionAttributes = fAttrs+          } -> do+            fv <- encodeM f+            let (argvs, argAttrs) = unzip args+            (n, argvs) <- encodeM argvs+            i <- liftIO $ FFI.buildCall builder fv argvs n s+            attrs <- encodeM $ MixedAttributeSet fAttrs rAttrs (Map.fromList (zip [0..] argAttrs))+            liftIO $ FFI.setCallSiteAttributeSet i attrs     +            tck <- encodeM tck+            liftIO $ FFI.setTailCallKind i tck+            cc <- encodeM cc+            liftIO $ FFI.setCallSiteCallingConvention i cc+            return' i+          A.Select { A.condition' = c, A.trueValue = t, A.falseValue = f } -> do+            c' <- encodeM c+            t' <- encodeM t+            f' <- encodeM f+            i <- liftIO $ FFI.buildSelect builder c' t' f' s+            return' i+          A.VAArg { A.argList = al, A.type' = t } -> do+            al' <- encodeM al+            t' <- encodeM t+            i <- liftIO $ FFI.buildVAArg builder al' t' s+            return' i+          A.ExtractElement { A.vector = v, A.index = idx } -> do+            v' <- encodeM v+            idx' <- encodeM idx+            i <- liftIO $ FFI.buildExtractElement builder v' idx' s+            return' i+          A.InsertElement { A.vector = v, A.element = e, A.index = idx } -> do+            v' <- encodeM v+            e' <- encodeM e+            idx' <- encodeM idx+            i <- liftIO $ FFI.buildInsertElement builder v' e' idx' s+            return' i+          A.ShuffleVector { A.operand0 = o0, A.operand1 = o1, A.mask = mask } -> do+            o0' <- encodeM o0+            o1' <- encodeM o1+            mask' <- encodeM mask+            i <- liftIO $ FFI.buildShuffleVector builder o0' o1' mask' s+            return' i+          A.ExtractValue { A.aggregate = a, A.indices' = is } -> do+            a' <- encodeM a+            (n, is') <- encodeM is+            i <- liftIO $ FFI.buildExtractValue builder a' is' n s+            return' i+          A.InsertValue { A.aggregate = a, A.element = e, A.indices' = is } -> do+            a' <- encodeM a+            e' <- encodeM e+            (n, is') <- encodeM is+            i <- liftIO $ FFI.buildInsertValue builder a' e' is' n s+            return' i+          A.LandingPad { +            A.type' = t,+            A.cleanup = cl, +            A.clauses = cs+          } -> do+            t' <- encodeM t+            i <- liftIO $ FFI.buildLandingPad builder t' (fromIntegral $ length cs) s+            forM cs $ \c -> +              case c of+                A.Catch a -> do+                  cn <- encodeM a+                  isArray <- liftIO $ isArrayType =<< FFI.typeOf (FFI.upCast cn)+                  when isArray $ throwError $ "Catch clause cannot take an array: " ++ show c+                  liftIO $ FFI.addClause i cn+                A.Filter a -> do+                  cn <- encodeM a+                  isArray <- liftIO $ isArrayType =<< FFI.typeOf (FFI.upCast cn)+                  unless isArray $ throwError $ "filter clause must take an array: " ++ show c+                  liftIO $ FFI.addClause i cn+            when cl $ do+              cl <- encodeM cl+              liftIO $ FFI.setCleanup i cl+            return' i+          A.Alloca { A.allocatedType = alt, A.numElements = n, A.alignment = alignment } -> do +             alt' <- encodeM alt+             n' <- encodeM n+             i <- liftIO $ FFI.buildAlloca builder alt' n' s+             unless (alignment == 0) $ liftIO $ FFI.setInstrAlignment i (fromIntegral alignment)+             return' i+          A.CleanupPad { A.parentPad = parentPad, A.args = args } -> do+            parentPad' <- encodeM parentPad+            (numArgs, args') <- encodeM args+            i <- liftIO $ FFI.buildCleanupPad builder parentPad' args' numArgs s+            return' i+          A.CatchPad { A.catchSwitch = catchSwitch, A.args = args } -> do+            catchSwitch' <- encodeM catchSwitch+            (numArgs, args') <- encodeM args+            i <- liftIO $ FFI.buildCatchPad builder catchSwitch' args' numArgs s+            return' i+          o -> $(TH.caseE [| o |] [+                   TH.match +                   (TH.recP fullName [ (f,) <$> (TH.varP . TH.mkName . TH.nameBase $ f) | f <- fieldNames ])+                   (TH.normalB (TH.doE handlerBody))+                   []+                   |+                   (name, ID.instructionKind -> k) <- Map.toList ID.instructionDefs,+                   case (k, name) of+                     (ID.Binary, _) -> True+                     (ID.Cast, _) -> True+                     (ID.Memory, "Alloca") -> False+                     (ID.Memory, _) -> True+                     _ -> False,+                   let+                     TH.RecC fullName (unzip3 -> (fieldNames, _, _)) = findInstrFields name+                     encodeMFields = map TH.nameBase fieldNames List.\\ [ "metadata" ]+                     handlerBody = ([+                       TH.bindS (if s == "fastMathFlags" then TH.tupP [] else TH.varP (TH.mkName s))+                           [| encodeM $(TH.dyn s) |] | s <- encodeMFields +                      ] ++ [+                       TH.bindS (TH.varP (TH.mkName "i")) [| liftIO $ $(+                          foldl1 TH.appE . map TH.dyn $ +                           [ "FFI.build" ++ name, "builder" ] ++ (encodeMFields List.\\ [ "fastMathFlags" ]) ++ [ "s" ] +                        ) |],+                       TH.noBindS [| return' $(TH.dyn "i") |]+                      ])+                  ]+                )++        setMD inst (A.metadata o)+        return (inst, act)+   |]+ )+++instance DecodeM DecodeAST a (Ptr FFI.Instruction) => DecodeM DecodeAST (DecodeAST (A.Named a)) (Ptr FFI.Instruction) where+  decodeM i = do+    t <- typeOf i+    w <- if t == A.VoidType then (return A.Do) else (return (A.:=) `ap` getLocalName i)+    return $ return w `ap` decodeM i++instance EncodeM EncodeAST a (Ptr FFI.Instruction) => EncodeM EncodeAST (A.Named a) (Ptr FFI.Instruction) where+  encodeM (A.Do o) = encodeM o+  encodeM (n A.:= o) = do+    i <- encodeM o+    let v = FFI.upCast i+    n' <- encodeM n+    liftIO $ FFI.setValueName v n'+    defineLocal n v+    return i++instance EncodeM EncodeAST a (Ptr FFI.Instruction, EncodeAST ()) => EncodeM EncodeAST (A.Named a) (EncodeAST ()) where+  encodeM (A.Do o) = liftM snd $ (encodeM o :: EncodeAST (Ptr FFI.Instruction, EncodeAST ()))+  encodeM (n A.:= o) = do+    (i, later) <- encodeM o+    let v = FFI.upCast (i :: Ptr FFI.Instruction)+    n' <- encodeM n+    liftIO $ FFI.setValueName v n'+    defineLocal n v+    return later++
+ src/LLVM/Internal/InstructionDefs.hs view
@@ -0,0 +1,71 @@+{-# LANGUAGE+  TemplateHaskell,+  CPP+  #-}+module LLVM.Internal.InstructionDefs (+  astInstructionRecs,+  astConstantRecs,+  instructionDefs,+  ID.InstructionKind(..),+  ID.InstructionDef(..),+  instrP,+  innerJoin,+  outerJoin+  ) where++import LLVM.Prelude++import qualified Language.Haskell.TH as TH+import qualified Language.Haskell.TH.Quote as TH++import Data.Map (Map)+import qualified Data.Map as Map++import qualified LLVM.Internal.FFI.InstructionDefs as ID++import qualified LLVM.AST.Instruction as A+import qualified LLVM.AST.Constant as A.C++$(do+   let ctorRecs t = do+#if __GLASGOW_HASKELL__ < 800+         TH.TyConI (TH.DataD _ _ _ cons _) <- TH.reify t+#else+         TH.TyConI (TH.DataD _ _ _ _ cons _) <- TH.reify t+#endif+         TH.dataToExpQ (const Nothing) $ [ (TH.nameBase n, rec) | rec@(TH.RecC n _) <- cons ]++   [d|+      astInstructionRecs :: Map String TH.Con+      astInstructionRecs = Map.fromList $(ctorRecs ''A.Instruction)+      astConstantRecs :: Map String TH.Con+      astConstantRecs = Map.fromList $(ctorRecs ''A.C.Constant)+    |]+ )++instructionDefs :: Map String ID.InstructionDef+instructionDefs = Map.fromList [ ((refName . ID.cAPIName $ i), i) | i <- ID.instructionDefs ]+  where+    refName "AtomicCmpXchg" = "CmpXchg"+    refName "PHI" = "Phi"+    refName x = x++innerJoin :: Ord k => Map k a -> Map k b -> Map k (a,b)+innerJoin = Map.intersectionWith (,)++outerJoin :: Ord k => Map k a -> Map k b -> Map k (Maybe a, Maybe b)+outerJoin xs ys = Map.unionWith combine+                  (Map.map (\a -> (Just a, Nothing)) xs)+                  (Map.map (\b -> (Nothing, Just b)) ys)+    where+      combine (Just a, Nothing) (Nothing, Just b) = (Just a, Just b)+      combine _ _ = error "outerJoin: the impossible happened"++instrP :: TH.QuasiQuoter+instrP = TH.QuasiQuoter {+  TH.quoteExp = undefined,+  TH.quotePat = let m = Map.fromList [ (ID.cAPIName i, ID.cppOpcode i) | i <- ID.instructionDefs ]+             in TH.dataToPatQ (const Nothing) . (m Map.!),+  TH.quoteType = undefined,+  TH.quoteDec = undefined+ }
+ src/LLVM/Internal/IntegerPredicate.hs view
@@ -0,0 +1,23 @@+{-# LANGUAGE+  TemplateHaskell,+  MultiParamTypeClasses+  #-}+module LLVM.Internal.IntegerPredicate where++import LLVM.Internal.Coding++import qualified LLVM.Internal.FFI.LLVMCTypes as FFI+import qualified LLVM.AST.IntegerPredicate as A.IPred++genCodingInstance [t| A.IPred.IntegerPredicate |] ''FFI.ICmpPredicate [+  (FFI.iCmpPredEQ, A.IPred.EQ),+  (FFI.iCmpPredNE, A.IPred.NE),+  (FFI.iCmpPredUGT, A.IPred.UGT),+  (FFI.iCmpPredUGE, A.IPred.UGE),+  (FFI.iCmpPredULT, A.IPred.ULT),+  (FFI.iCmpPredULE, A.IPred.ULE),+  (FFI.iCmpPredSGT, A.IPred.SGT),+  (FFI.iCmpPredSGE, A.IPred.SGE),+  (FFI.iCmpPredSLT, A.IPred.SLT),+  (FFI.iCmpPredSLE, A.IPred.SLE)+ ]
+ src/LLVM/Internal/LibraryFunction.hsc view
@@ -0,0 +1,37 @@+{-# LANGUAGE+  MultiParamTypeClasses+ #-}+module LLVM.Internal.LibraryFunction where++import LLVM.Prelude++import qualified LLVM.Internal.FFI.LLVMCTypes as FFI++import LLVM.Internal.Coding++#include "LLVM/Internal/FFI/LibFunc.h"++#{+define hsc_inject(m) { \+  struct { const char *s; unsigned n; } *p, list[] = { LLVM_HS_FOR_EACH_LIB_FUNC(m) }; \+  hsc_printf("data LibraryFunction\n"); \+  for(p = list; p < list + sizeof(list)/sizeof(list[0]); ++p) { \+    hsc_printf("  %s LF__%s\n", (p == list ? "=" : "|"), p->s); \+  } \+  hsc_printf("  deriving (Eq, Ord, Enum, Bounded, Read, Show)"); \+  hsc_printf("\n"); \+  hsc_printf("instance Monad m => EncodeM m LibraryFunction FFI.LibFunc where\n"); \+  for(p = list; p < list + sizeof(list)/sizeof(list[0]); ++p) { \+    hsc_printf("  encodeM LF__%s = return (FFI.LibFunc %u)\n", p->s, p->n); \+  } \+  hsc_printf("\n"); \+  hsc_printf("instance Monad m => DecodeM m LibraryFunction FFI.LibFunc where\n"); \+  for(p = list; p < list + sizeof(list)/sizeof(list[0]); ++p) { \+    hsc_printf("  decodeM (FFI.LibFunc %u) = return LF__%s \n", p->n, p->s); \+  } \+}+}++-- | <http://llvm.org/doxygen/namespacellvm_1_1LibFunc.html#abf8f6830387f338fed0bce2e65108c6f>+#define Mac(n) { #n, LLVMLibFunc__ ## n },+#{inject Mac}
+ src/LLVM/Internal/MemoryBuffer.hs view
@@ -0,0 +1,57 @@+{-# LANGUAGE+  MultiParamTypeClasses,+  UndecidableInstances+  #-}+module LLVM.Internal.MemoryBuffer where++import LLVM.Prelude++import Control.Exception+import Control.Monad.AnyCont+import Control.Monad.Error.Class+import Control.Monad.IO.Class+import qualified Data.ByteString as BS+import qualified Data.ByteString.Unsafe as BS+import Foreign.Ptr++import LLVM.Internal.Coding+import LLVM.Internal.String+import LLVM.Internal.Inject+import qualified LLVM.Internal.FFI.LLVMCTypes as FFI+import qualified LLVM.Internal.FFI.MemoryBuffer as FFI++data Specification +  = Bytes { name :: String,  content :: BS.ByteString }+  | File { pathName :: String }++instance (Inject String e, MonadError e m, Monad m, MonadIO m, MonadAnyCont IO m) => EncodeM m Specification (FFI.OwnerTransfered (Ptr FFI.MemoryBuffer)) where+  encodeM spec = liftM FFI.OwnerTransfered $ do+    case spec of+      Bytes name content -> do+        (s,l) <- anyContToM $ BS.unsafeUseAsCStringLen (BS.snoc content 0)+        name <- encodeM name+        nullTerminate <- encodeM True+        liftIO $ FFI.createMemoryBufferWithMemoryRange s (fromIntegral (l-1)) name nullTerminate+      File pathName -> do+        pathName <- encodeM pathName+        mbPtr <- alloca+        msgPtr <- alloca+        result <- decodeM =<< (liftIO $ FFI.createMemoryBufferWithContentsOfFile pathName mbPtr msgPtr)+        when result $ do+          msg <- decodeM msgPtr+          throwError (inject (msg :: String))+        peek mbPtr          ++instance (Inject String e, MonadError e m, Monad m, MonadIO m, MonadAnyCont IO m) => EncodeM m Specification (Ptr FFI.MemoryBuffer) where+  encodeM spec = do+    FFI.OwnerTransfered mb <- encodeM spec+    anyContToM $ bracket (return mb) FFI.disposeMemoryBuffer++instance MonadIO d => DecodeM d BS.ByteString (Ptr FFI.MemoryBuffer) where+  decodeM p = do+    s <- liftIO $ FFI.getBufferStart p+    l <- liftIO $ FFI.getBufferSize p+    liftIO $ BS.packCStringLen (s, fromIntegral l)++instance MonadIO d => DecodeM d String (Ptr FFI.MemoryBuffer) where+  decodeM = decodeM . UTF8ByteString <=< decodeM
+ src/LLVM/Internal/Metadata.hs view
@@ -0,0 +1,56 @@+{-# LANGUAGE+  MultiParamTypeClasses+  #-}+module LLVM.Internal.Metadata where++import LLVM.Prelude++import Control.Monad.State hiding (mapM, forM)+import Control.Monad.AnyCont++import Foreign.Ptr++import qualified Foreign.Marshal.Array as FMA+import qualified Data.Array as Array++import qualified LLVM.Internal.FFI.LLVMCTypes as FFI+import qualified LLVM.Internal.FFI.Metadata as FFI+import qualified LLVM.Internal.FFI.PtrHierarchy as FFI++import LLVM.Internal.Context+import LLVM.Internal.Coding+import LLVM.Internal.EncodeAST+import LLVM.Internal.DecodeAST+import LLVM.Internal.Value ()++instance EncodeM EncodeAST String FFI.MDKindID where+  encodeM s = do+    Context c <- gets encodeStateContext+    s <- encodeM s+    liftIO $ FFI.getMDKindIDInContext c s++getMetadataKindNames :: Context -> DecodeAST ()+getMetadataKindNames (Context c) = scopeAnyCont $ do+  let g n = do+        ps <- allocaArray n+        ls <- allocaArray n +        n' <- liftIO $ FFI.getMDKindNames c ps ls n+        if n' > n+         then g n'+         else do+           csls <- return zip+                   `ap` liftIO (FMA.peekArray (fromIntegral n') ps)+                   `ap` liftIO (FMA.peekArray (fromIntegral n') ls)+           mapM decodeM csls+  strs <- g 16+  modify $ \s -> s { metadataKinds = Array.listArray (0, fromIntegral (length strs) - 1) strs }++instance DecodeM DecodeAST String FFI.MDKindID where+  decodeM (FFI.MDKindID k) = gets $ (Array.! (fromIntegral k)) . metadataKinds++instance DecodeM DecodeAST String (Ptr FFI.MDString) where+  decodeM p = do+    np <- alloca+    s <- liftIO $ FFI.getMDString p np+    n <- peek np+    decodeM (s, n)
+ src/LLVM/Internal/Module.hs view
@@ -0,0 +1,526 @@+{-#+  LANGUAGE+  TemplateHaskell,+  ScopedTypeVariables,+  MultiParamTypeClasses+  #-}+-- | This Haskell module is for/of functions for handling LLVM modules.+module LLVM.Internal.Module where++import LLVM.Prelude++import Control.Exception+import Control.Monad.AnyCont+import Control.Monad.Error.Class+import Control.Monad.Trans.Except+import Control.Monad.State (gets)+import Control.Monad.Trans++import Foreign.Ptr+import Foreign.C+import Data.IORef+import qualified Data.ByteString as BS+import qualified Data.Map as Map++import qualified LLVM.Internal.FFI.Assembly as FFI+import qualified LLVM.Internal.FFI.Builder as FFI+import qualified LLVM.Internal.FFI.Bitcode as FFI+import qualified LLVM.Internal.FFI.Function as FFI+import qualified LLVM.Internal.FFI.GlobalAlias as FFI+import qualified LLVM.Internal.FFI.GlobalValue as FFI+import qualified LLVM.Internal.FFI.GlobalVariable as FFI+import qualified LLVM.Internal.FFI.Iterate as FFI+import qualified LLVM.Internal.FFI.LLVMCTypes as FFI+import qualified LLVM.Internal.FFI.MemoryBuffer as FFI+import qualified LLVM.Internal.FFI.Metadata as FFI+import qualified LLVM.Internal.FFI.Module as FFI+import qualified LLVM.Internal.FFI.PtrHierarchy as FFI+import qualified LLVM.Internal.FFI.RawOStream as FFI+import qualified LLVM.Internal.FFI.Target as FFI+import qualified LLVM.Internal.FFI.Value as FFI++import LLVM.Internal.Attribute+import LLVM.Internal.BasicBlock  +import LLVM.Internal.Coding+import LLVM.Internal.Context+import LLVM.Internal.DecodeAST+import LLVM.Internal.EncodeAST+import LLVM.Internal.Function+import LLVM.Internal.Global+import LLVM.Internal.Inject+import LLVM.Internal.Instruction ()+import qualified LLVM.Internal.MemoryBuffer as MB+import LLVM.Internal.Metadata+import LLVM.Internal.Operand+import LLVM.Internal.RawOStream+import LLVM.Internal.String+import LLVM.Internal.Target+import LLVM.Internal.Type+import LLVM.Internal.Value++import LLVM.DataLayout+import LLVM.Diagnostic++import qualified LLVM.AST as A+import qualified LLVM.AST.DataLayout as A+import qualified LLVM.AST.AddrSpace as A+import qualified LLVM.AST.Global as A.G++-- | <http://llvm.org/doxygen/classllvm_1_1Module.html>+newtype Module = Module (IORef (Ptr FFI.Module))++newModule :: Ptr FFI.Module -> IO (Module)+newModule m = fmap Module (newIORef m)++readModule :: MonadIO m => Module -> m (Ptr FFI.Module)+readModule (Module ref) = liftIO $ readIORef ref++-- | Signal that a module does no longer exist and thus must not be+-- disposed. It is the responsibility of the caller to ensure that the+-- module has been disposed. If you use only the functions provided by+-- llvm-hs you should never call this yourself.+deleteModule :: Module -> IO ()+deleteModule (Module r) = writeIORef r nullPtr++-- | A newtype to distinguish strings used for paths from other strings+newtype File = File FilePath+  deriving (Eq, Ord, Read, Show)++instance Inject String (Either String Diagnostic) where+    inject = Left++-- | link LLVM modules - move or copy parts of a source module into a+-- destination module.  Note that this operation is not commutative -+-- not only concretely (e.g. the destination module is modified,+-- becoming the result) but abstractly (e.g. unused private globals in+-- the source module do not appear in the result, but similar globals+-- in the destination remain). The source module is destroyed.+linkModules ::+     Module -- ^ The module into which to link+  -> Module -- ^ The module to link into the other (this module is destroyed)+  -> ExceptT String IO ()+linkModules dest src  = flip runAnyContT return $ do+  dest' <- readModule dest+  src' <- readModule src+  result <- decodeM =<< liftIO (FFI.linkModules dest' src')+  -- linkModules takes care of deleting the sourcemodule+  liftIO $ deleteModule src+  when result (throwError "Couldn’t link modules")++class LLVMAssemblyInput s where+  llvmAssemblyMemoryBuffer :: (Inject String e, MonadError e m, MonadIO m, MonadAnyCont IO m)+                              => s -> m (FFI.OwnerTransfered (Ptr FFI.MemoryBuffer))++instance LLVMAssemblyInput (String, String) where+  llvmAssemblyMemoryBuffer (id, s) = do+    UTF8ByteString bs <- encodeM s+    encodeM (MB.Bytes id bs)++instance LLVMAssemblyInput String where+  llvmAssemblyMemoryBuffer s = llvmAssemblyMemoryBuffer ("<string>", s)++instance LLVMAssemblyInput File where+  llvmAssemblyMemoryBuffer (File p) = encodeM (MB.File p)++-- | parse 'Module' from LLVM assembly+withModuleFromLLVMAssembly :: LLVMAssemblyInput s+                              => Context -> s -> (Module -> IO a) -> ExceptT String IO a+withModuleFromLLVMAssembly (Context c) s f = flip runAnyContT return $ do+  mb <- llvmAssemblyMemoryBuffer s+  msgPtr <- alloca+  m <- anyContToM $ bracket (newModule =<< FFI.parseLLVMAssembly c mb msgPtr) (FFI.disposeModule <=< readModule)+  m' <- readModule m+  when (m' == nullPtr) $ throwError =<< decodeM msgPtr+  liftIO $ f m++-- | generate LLVM assembly from a 'Module'+moduleLLVMAssembly :: Module -> IO String+moduleLLVMAssembly m = do+  resultRef <- newIORef Nothing+  let saveBuffer :: Ptr CChar -> CSize -> IO ()+      saveBuffer start size = do+        r <- decodeM (start, fromIntegral size)+        writeIORef resultRef (Just r)+  m' <- readModule m+  FFI.withBufferRawPWriteStream saveBuffer $ FFI.writeLLVMAssembly m' . FFI.upCast+  Just s <- readIORef resultRef+  return s++-- | write LLVM assembly for a 'Module' to a file+writeLLVMAssemblyToFile :: File -> Module -> ExceptT String IO ()+writeLLVMAssemblyToFile (File path) m = flip runAnyContT return $ do+  m' <- readModule m+  withFileRawOStream path False True $ liftIO . (FFI.writeLLVMAssembly m')++class BitcodeInput b where+  bitcodeMemoryBuffer :: (Inject String e, MonadError e m, MonadIO m, MonadAnyCont IO m)+                         => b -> m (Ptr FFI.MemoryBuffer)++instance BitcodeInput (String, BS.ByteString) where+  bitcodeMemoryBuffer (s, bs) = encodeM (MB.Bytes s bs)++instance BitcodeInput File where+  bitcodeMemoryBuffer (File p) = encodeM (MB.File p)++-- | parse 'Module' from LLVM bitcode+withModuleFromBitcode :: BitcodeInput b => Context -> b -> (Module -> IO a) -> ExceptT String IO a+withModuleFromBitcode (Context c) b f = flip runAnyContT return $ do+  mb <- bitcodeMemoryBuffer b+  msgPtr <- alloca+  m <- anyContToM $ bracket (newModule =<< FFI.parseBitcode c mb msgPtr) (FFI.disposeModule <=< readModule)+  m' <- readModule m+  when (m' == nullPtr) $ throwError =<< decodeM msgPtr+  liftIO $ f m++-- | generate LLVM bitcode from a 'Module'+moduleBitcode :: Module -> IO BS.ByteString+moduleBitcode m = do+  m' <- readModule m+  r <- runExceptT $ withBufferRawOStream (liftIO . FFI.writeBitcode m')+  either fail return r++-- | write LLVM bitcode from a 'Module' into a file+writeBitcodeToFile :: File -> Module -> ExceptT String IO ()+writeBitcodeToFile (File path) m = flip runAnyContT return $ do+  m' <- readModule m+  withFileRawOStream path False False $ liftIO . FFI.writeBitcode m'++targetMachineEmit :: FFI.CodeGenFileType -> TargetMachine -> Module -> Ptr FFI.RawPWriteStream -> ExceptT String IO ()+targetMachineEmit fileType (TargetMachine tm) m os = flip runAnyContT return $ do+  msgPtr <- alloca+  m' <- readModule m+  r <- decodeM =<< (liftIO $ FFI.targetMachineEmit tm m' os fileType msgPtr)+  when r $ throwError =<< decodeM msgPtr++emitToFile :: FFI.CodeGenFileType -> TargetMachine -> File -> Module -> ExceptT String IO ()+emitToFile fileType tm (File path) m = flip runAnyContT return $ do+  withFileRawPWriteStream path False False $ targetMachineEmit fileType tm m++emitToByteString :: FFI.CodeGenFileType -> TargetMachine -> Module -> ExceptT String IO BS.ByteString+emitToByteString fileType tm m = flip runAnyContT return $ do+  withBufferRawPWriteStream $ targetMachineEmit fileType tm m++-- | write target-specific assembly directly into a file+writeTargetAssemblyToFile :: TargetMachine -> File -> Module -> ExceptT String IO ()+writeTargetAssemblyToFile = emitToFile FFI.codeGenFileTypeAssembly++-- | produce target-specific assembly as a 'String'+moduleTargetAssembly :: TargetMachine -> Module -> ExceptT String IO String+moduleTargetAssembly tm m = decodeM . UTF8ByteString =<< emitToByteString FFI.codeGenFileTypeAssembly tm m++-- | produce target-specific object code as a 'ByteString'+moduleObject :: TargetMachine -> Module -> ExceptT String IO BS.ByteString+moduleObject = emitToByteString FFI.codeGenFileTypeObject++-- | write target-specific object code directly into a file+writeObjectToFile :: TargetMachine -> File -> Module -> ExceptT String IO ()+writeObjectToFile = emitToFile FFI.codeGenFileTypeObject++setTargetTriple :: Ptr FFI.Module -> String -> EncodeAST ()+setTargetTriple m t = do+  t <- encodeM t+  liftIO $ FFI.setTargetTriple m t++getTargetTriple :: Ptr FFI.Module -> IO (Maybe String)+getTargetTriple m = do+  s <- decodeM =<< liftIO (FFI.getTargetTriple m)+  return $ if s == "" then Nothing else Just s++setDataLayout :: Ptr FFI.Module -> A.DataLayout -> EncodeAST ()+setDataLayout m dl = do+  s <- encodeM (dataLayoutToString dl)+  liftIO $ FFI.setDataLayout m s++getDataLayout :: Ptr FFI.Module -> IO (Maybe A.DataLayout)+getDataLayout m = do+  dlString <- decodeM =<< FFI.getDataLayout m+  either fail return . runExcept . parseDataLayout A.BigEndian $ dlString++-- | This function will call disposeModule after the callback+-- exits. Calling 'deleteModule' prevents double free errors. As long+-- as you only call functions provided by llvm-hs this should not+-- be necessary since llvm-hs takes care of this.+withModuleFromAST :: Context -> A.Module -> (Module -> IO a) -> ExceptT String IO a+withModuleFromAST context@(Context c) (A.Module moduleId sourceFileName dataLayout triple definitions) f = runEncodeAST context $ do+  moduleId <- encodeM moduleId+  m <- anyContToM $ bracket (newModule =<< FFI.moduleCreateWithNameInContext moduleId c) (FFI.disposeModule <=< readModule)+  ffiMod <- readModule m+  sourceFileName' <- encodeM sourceFileName+  liftIO $ FFI.setSourceFileName ffiMod sourceFileName'+  Context context <- gets encodeStateContext+  maybe (return ()) (setDataLayout ffiMod) dataLayout+  maybe (return ()) (setTargetTriple ffiMod) triple+  let sequencePhases :: EncodeAST [EncodeAST (EncodeAST (EncodeAST (EncodeAST ())))] -> EncodeAST ()+      sequencePhases l = (l >>= (sequence >=> sequence >=> sequence >=> sequence)) >> (return ())+  sequencePhases $ forM definitions $ \d -> case d of+   A.TypeDefinition n t -> do+     t' <- createNamedType n+     defineType n t'+     return $ do+       maybe (return ()) (setNamedType t') t+       return . return . return . return $ ()++   A.COMDAT n csk -> do+     n' <- encodeM n+     csk <- encodeM csk+     cd <- liftIO $ FFI.getOrInsertCOMDAT ffiMod n'+     liftIO $ FFI.setCOMDATSelectionKind cd csk+     defineCOMDAT n cd+     return . return . return . return . return $ ()+     +   A.MetadataNodeDefinition i os -> return . return $ do+     t <- liftIO $ FFI.createTemporaryMDNodeInContext context+     defineMDNode i t+     return $ do+       n <- encodeM (A.MetadataNode os)+       liftIO $ FFI.metadataReplaceAllUsesWith (FFI.upCast t) (FFI.upCast n)+       defineMDNode i n+       return $ return ()++   A.NamedMetadataDefinition n ids -> return . return . return . return $ do+     n <- encodeM n+     ids <- encodeM (map A.MetadataNodeReference ids)+     nm <- liftIO $ FFI.getOrAddNamedMetadata ffiMod n+     liftIO $ FFI.namedMetadataAddOperands nm ids+     return ()++   A.ModuleInlineAssembly s -> do+     s <- encodeM s+     liftIO $ FFI.moduleAppendInlineAsm ffiMod (FFI.ModuleAsm s)+     return . return . return . return . return $ ()++   A.FunctionAttributes gid attrs -> do+     attrs <- encodeM attrs+     defineAttributeGroup gid attrs+     return . return . return . return . return $ ()++   A.GlobalDefinition g -> return . phase $ do+     eg' :: EncodeAST (Ptr FFI.GlobalValue) <- case g of+       g@(A.GlobalVariable { A.G.name = n }) -> do+         typ <- encodeM (A.G.type' g)+         g' <- liftIO $ withName n $ \gName ->+                   FFI.addGlobalInAddressSpace ffiMod typ gName+                          (fromIntegral ((\(A.AddrSpace a) -> a) $ A.G.addrSpace g))+         defineGlobal n g'+         setThreadLocalMode g' (A.G.threadLocalMode g)+         liftIO $ do+           hua <- encodeM (A.G.unnamedAddr g)+           FFI.setUnnamedAddr (FFI.upCast g') hua+           ic <- encodeM (A.G.isConstant g)+           FFI.setGlobalConstant g' ic+         return $ do+           maybe (return ()) ((liftIO . FFI.setInitializer g') <=< encodeM) (A.G.initializer g)+           setSection g' (A.G.section g)+           setCOMDAT g' (A.G.comdat g)+           setAlignment g' (A.G.alignment g)+           return (FFI.upCast g')+       (a@A.G.GlobalAlias { A.G.name = n }) -> do+         let A.PointerType typ as = A.G.type' a+         typ <- encodeM typ+         as <- encodeM as+         a' <- liftIO $ withName n $ \name -> FFI.justAddAlias ffiMod typ as name+         defineGlobal n a'+         liftIO $ do+           hua <- encodeM (A.G.unnamedAddr a)+           FFI.setUnnamedAddr (FFI.upCast a') hua+         return $ do+           setThreadLocalMode a' (A.G.threadLocalMode a)+           (liftIO . FFI.setAliasee a') =<< encodeM (A.G.aliasee a)+           return (FFI.upCast a')+       (A.Function _ _ _ cc rAttrs resultType fName (args, isVarArgs) attrs _ _ _ gc prefix blocks personality) -> do+         typ <- encodeM $ A.FunctionType resultType [t | A.Parameter t _ _ <- args] isVarArgs+         f <- liftIO . withName fName $ \fName -> FFI.addFunction ffiMod fName typ+         defineGlobal fName f+         cc <- encodeM cc+         liftIO $ FFI.setFunctionCallingConvention f cc+         setFunctionAttributes f (MixedAttributeSet attrs rAttrs (Map.fromList $ zip [0..] [pa | A.Parameter _ _ pa <- args]))+         setPrefixData f prefix+         setSection f (A.G.section g)+         setCOMDAT f (A.G.comdat g)+         setAlignment f (A.G.alignment g)+         setGC f gc+         setPersonalityFn f personality+         forM blocks $ \(A.BasicBlock bName _ _) -> do+           b <- liftIO $ withName bName $ \bName -> FFI.appendBasicBlockInContext context f bName+           defineBasicBlock fName bName b+         phase $ do+           let nParams = length args+           ps <- allocaArray nParams+           liftIO $ FFI.getParams f ps+           params <- peekArray nParams ps+           forM (zip args params) $ \(A.Parameter _ n _, p) -> do+             defineLocal n p+             n <- encodeM n+             liftIO $ FFI.setValueName (FFI.upCast p) n+           finishInstrs <- forM blocks $ \(A.BasicBlock bName namedInstrs term) -> do+             b <- encodeM bName+             (do+               builder <- gets encodeStateBuilder+               liftIO $ FFI.positionBuilderAtEnd builder b)+             finishes <- mapM encodeM namedInstrs :: EncodeAST [EncodeAST ()]+             (encodeM term :: EncodeAST (Ptr FFI.Instruction))+             return (sequence_ finishes)+           sequence_ finishInstrs+           locals <- gets $ Map.toList . encodeStateLocals+           forM [ n | (n, ForwardValue _) <- locals ] $ \n -> undefinedReference "local" n+           return (FFI.upCast f)+     return $ do+       g' <- eg'+       setLinkage g' (A.G.linkage g)+       setVisibility g' (A.G.visibility g)+       setDLLStorageClass g' (A.G.dllStorageClass g)+       return $ return ()+  liftIO $ f m+++-- This returns a nested DecodeAST to allow interleaving of different+-- decoding steps. Take a look at the call site in moduleAST for more+-- details.+decodeGlobalVariables :: Ptr FFI.Module -> DecodeAST (DecodeAST [A.G.Global])+decodeGlobalVariables mod = do+  ffiGlobals <- liftIO $ FFI.getXs (FFI.getFirstGlobal mod) FFI.getNextGlobal+  fmap sequence . forM ffiGlobals $ \g -> do+    A.PointerType t as <- typeOf g+    n <- getGlobalName g+    return $+      A.GlobalVariable+        <$> return n+        <*> getLinkage g+        <*> getVisibility g+        <*> getDLLStorageClass g+        <*> getThreadLocalMode g+        <*> return as+        <*> (liftIO $ decodeM =<< FFI.getUnnamedAddr (FFI.upCast g))+        <*> (liftIO $ decodeM =<< FFI.isGlobalConstant g)+        <*> return t+        <*> (do i <- liftIO $ FFI.getInitializer g+                if i == nullPtr+                  then return Nothing+                  else Just <$> decodeM i)+        <*> getSection g+        <*> getCOMDATName g+        <*> getAlignment g++-- This returns a nested DecodeAST to allow interleaving of different+-- decoding steps. Take a look at the call site in moduleAST for more+-- details.+decodeGlobalAliases :: Ptr FFI.Module -> DecodeAST (DecodeAST [A.G.Global])+decodeGlobalAliases mod = do+  ffiAliases <- liftIO $ FFI.getXs (FFI.getFirstAlias mod) FFI.getNextAlias+  fmap sequence . forM ffiAliases $ \a -> do+    n <- getGlobalName a+    return $+      A.G.GlobalAlias+        <$> return n+        <*> getLinkage a+        <*> getVisibility a+        <*> getDLLStorageClass a+        <*> getThreadLocalMode a+        <*> (liftIO $ decodeM =<< FFI.getUnnamedAddr (FFI.upCast a))+        <*> typeOf a+        <*> (decodeM =<< (liftIO $ FFI.getAliasee a))++-- This returns a nested DecodeAST to allow interleaving of different+-- decoding steps. Take a look at the call site in moduleAST for more+-- details.+decodeFunctions :: Ptr FFI.Module -> DecodeAST (DecodeAST [A.G.Global])+decodeFunctions mod = do+  ffiFunctions <-+    liftIO $ FFI.getXs (FFI.getFirstFunction mod) FFI.getNextFunction+  fmap sequence . forM ffiFunctions $ \f ->+    localScope $ do+      A.PointerType (A.FunctionType returnType _ isVarArg) _ <- typeOf f+      n <- getGlobalName f+      MixedAttributeSet fAttrs rAttrs pAttrs <- getMixedAttributeSet f+      parameters <- getParameters f pAttrs+      decodeBlocks <- do+        ffiBasicBlocks <-+          liftIO $ FFI.getXs (FFI.getFirstBasicBlock f) FFI.getNextBasicBlock+        fmap sequence . forM ffiBasicBlocks $ \b -> do+          n <- getLocalName b+          decodeInstructions <- getNamedInstructions b+          decodeTerminator <- getBasicBlockTerminator b+          return $+            A.BasicBlock+              <$> return n+              <*> decodeInstructions+              <*> decodeTerminator+      return $+        A.Function+          <$> getLinkage f+          <*> getVisibility f+          <*> getDLLStorageClass f+          <*> (liftIO $ decodeM =<< FFI.getFunctionCallingConvention f)+          <*> return rAttrs+          <*> return returnType+          <*> return n+          <*> return (parameters, isVarArg)+          <*> return fAttrs+          <*> getSection f+          <*> getCOMDATName f+          <*> getAlignment f+          <*> getGC f+          <*> getPrefixData f+          <*> decodeBlocks+          <*> getPersonalityFn f++decodeNamedMetadataDefinitions :: Ptr FFI.Module -> DecodeAST [A.Definition]+decodeNamedMetadataDefinitions mod = do+  ffiNamedMetadataNodes <-+    liftIO $ FFI.getXs (FFI.getFirstNamedMetadata mod) FFI.getNextNamedMetadata+  forM ffiNamedMetadataNodes $ \nm ->+    scopeAnyCont $ do+      n <- liftIO $ FFI.getNamedMetadataNumOperands nm+      os <- allocaArray n+      liftIO $ FFI.getNamedMetadataOperands nm os+      A.NamedMetadataDefinition+        <$> (decodeM $ FFI.getNamedMetadataName nm)+        <*> fmap+              (map (\(A.MetadataNodeReference mid) -> mid))+              (decodeM (n, os))++-- | Get an LLVM.AST.'LLVM.AST.Module' from a LLVM.'Module' - i.e.+-- raise C++ objects into an Haskell AST.+moduleAST :: Module -> IO A.Module+moduleAST m = runDecodeAST $ do+  mod <- readModule m+  c <- return Context `ap` liftIO (FFI.getModuleContext mod)+  getMetadataKindNames c+  A.Module+    <$> (liftIO $ decodeM =<< FFI.getModuleIdentifier mod)+    <*> (liftIO $ decodeM =<< FFI.getSourceFileName mod)+    <*> (liftIO $ getDataLayout mod)+    <*> (liftIO $ do+           s <- decodeM =<< FFI.getTargetTriple mod+           return $ if s == "" then Nothing else Just s)+    <*> (do+      globalDefinitions <-+        map A.GlobalDefinition . concat <$>+        -- Variables, aliases & functions can reference each other. To+        -- resolve this references properly during decoding a two step+        -- process is used: In the first step, the names of the+        -- different definitions are stored. In the second step we can+        -- then decode the definitions and look up the previously+        -- stored references.+        (join . fmap sequence . sequence)+          [ decodeGlobalVariables mod+          , decodeGlobalAliases mod+          , decodeFunctions mod+          ]+      structDefinitions <- getStructDefinitions+      inlineAsm <- decodeM =<< liftIO (FFI.moduleGetInlineAsm mod)+      namedMetadata <- decodeNamedMetadataDefinitions mod+      metadata <- getMetadataDefinitions+      functionAttributes <- do+        functionAttributes <- gets $ Map.toList . functionAttributeSetIDs+        forM functionAttributes $ \(as, gid) ->+          A.FunctionAttributes <$> return gid <*> decodeM as+      comdats <- gets $ map (uncurry A.COMDAT) . Map.elems . comdats+      return $+        structDefinitions +++        inlineAsm +++        globalDefinitions +++        namedMetadata +++        metadata +++        functionAttributes +++        comdats)
+ src/LLVM/Internal/Operand.hs view
@@ -0,0 +1,131 @@+{-# LANGUAGE+  MultiParamTypeClasses+  #-}+module LLVM.Internal.Operand where++import LLVM.Prelude++import Control.Monad.State+import Control.Monad.AnyCont+import qualified Data.Map as Map++import Foreign.Ptr++import qualified LLVM.Internal.FFI.Constant as FFI+import qualified LLVM.Internal.FFI.InlineAssembly as FFI+import qualified LLVM.Internal.FFI.Metadata as FFI+import qualified LLVM.Internal.FFI.PtrHierarchy as FFI+import qualified LLVM.Internal.FFI.Value as FFI++import LLVM.Internal.Coding+import LLVM.Internal.Constant ()+import LLVM.Internal.Context+import LLVM.Internal.DecodeAST+import LLVM.Internal.EncodeAST+import LLVM.Internal.InlineAssembly ()+import LLVM.Internal.Metadata ()++import qualified LLVM.AST as A++instance DecodeM DecodeAST A.Operand (Ptr FFI.Value) where+  decodeM v = do+    c <- liftIO $ FFI.isAConstant v+    if (c /= nullPtr) +     then+      return A.ConstantOperand `ap` decodeM c+     else+      do m <- liftIO $ FFI.isAMetadataOperand v+         if (m /= nullPtr)+            then A.MetadataOperand <$> decodeM m+            else return A.LocalReference+                           `ap` (decodeM =<< (liftIO $ FFI.typeOf v))+                           `ap` getLocalName v++instance DecodeM DecodeAST A.Metadata (Ptr FFI.Metadata) where+  decodeM md = do+    s <- liftIO $ FFI.isAMDString md+    if (s /= nullPtr)+       then A.MDString <$> decodeM s+       else do n <- liftIO $ FFI.isAMDNode md+               if (n /= nullPtr)+                  then A.MDNode <$> decodeM n+                  else do v <- liftIO $ FFI.isAMDValue md+                          if (v /= nullPtr)+                              then A.MDValue <$> decodeM v+                              else fail "Metadata was not one of [MDString, MDValue, MDNode]"++instance DecodeM DecodeAST A.CallableOperand (Ptr FFI.Value) where+  decodeM v = do+    ia <- liftIO $ FFI.isAInlineAsm v+    if ia /= nullPtr+     then liftM Left (decodeM ia)+     else liftM Right (decodeM v)++instance EncodeM EncodeAST A.Operand (Ptr FFI.Value) where+  encodeM (A.ConstantOperand c) = (FFI.upCast :: Ptr FFI.Constant -> Ptr FFI.Value) <$> encodeM c+  encodeM (A.LocalReference t n) = do+    lv <- refer encodeStateLocals n $ do+      lv <- do+        n <- encodeM n+        t <- encodeM t+        v <- liftIO $ FFI.createArgument t n+        return $ ForwardValue v+      modify $ \s -> s { encodeStateLocals = Map.insert n lv $ encodeStateLocals s }+      return lv+    return $ case lv of DefinedValue v -> v; ForwardValue v -> v+  encodeM (A.MetadataOperand md) = do+    md' <- encodeM md+    Context c <- gets encodeStateContext+    liftIO $ FFI.upCast <$> FFI.metadataOperand c md'++instance EncodeM EncodeAST A.Metadata (Ptr FFI.Metadata) where+  encodeM (A.MDString s) = do+    Context c <- gets encodeStateContext+    s <- encodeM s+    liftM FFI.upCast $ liftIO $ FFI.mdStringInContext c s+  encodeM (A.MDNode mdn) = (FFI.upCast :: Ptr FFI.MDNode -> Ptr FFI.Metadata) <$> encodeM mdn+  encodeM (A.MDValue v) = do+     v <- encodeM v+     liftIO $ FFI.upCast <$> FFI.mdValue v++instance EncodeM EncodeAST A.CallableOperand (Ptr FFI.Value) where+  encodeM (Right o) = encodeM o+  encodeM (Left i) = liftM (FFI.upCast :: Ptr FFI.InlineAsm -> Ptr FFI.Value) (encodeM i)++instance EncodeM EncodeAST A.MetadataNode (Ptr FFI.MDNode) where+  encodeM (A.MetadataNode ops) = scopeAnyCont $ do+    Context c <- gets encodeStateContext+    ops <- encodeM ops+    liftIO $ FFI.createMDNodeInContext c ops+  encodeM (A.MetadataNodeReference n) = referMDNode n++instance DecodeM DecodeAST [Maybe A.Metadata] (Ptr FFI.MDNode) where+  decodeM p = scopeAnyCont $ do+    n <- liftIO $ FFI.getMDNodeNumOperands p+    ops <- allocaArray n+    liftIO $ FFI.getMDNodeOperands p ops+    decodeM (n, ops)++instance DecodeM DecodeAST A.Operand (Ptr FFI.MDValue) where+  decodeM = decodeM <=< liftIO . FFI.getMDValue++instance DecodeM DecodeAST A.Metadata (Ptr FFI.MetadataAsVal) where+  decodeM = decodeM <=< liftIO . FFI.getMetadataOperand++instance DecodeM DecodeAST A.MetadataNode (Ptr FFI.MDNode) where+  decodeM p = scopeAnyCont $ do++    -- fl <- decodeM =<< liftIO (FFI.mdNodeIsFunctionLocal p)+    -- if fl+    --  then+    --    return A.MetadataNode `ap` decodeM p+    --  else+       return A.MetadataNodeReference `ap` getMetadataNodeID p++getMetadataDefinitions :: DecodeAST [A.Definition]+getMetadataDefinitions = fix $ \continue -> do+  mdntd <- takeMetadataNodeToDefine+  flip (maybe (return [])) mdntd $ \(mid, p) -> do+    return (:)+      `ap` (return A.MetadataNodeDefinition `ap` return mid `ap` decodeM p)+      `ap` continue
+ src/LLVM/Internal/OrcJIT.hs view
@@ -0,0 +1,107 @@+{-# LANGUAGE MultiParamTypeClasses #-}+module LLVM.Internal.OrcJIT where++import LLVM.Prelude++import Control.Exception+import Control.Monad.AnyCont+import Control.Monad.IO.Class+import Data.Bits+import Data.ByteString (ByteString, packCString, useAsCString)+import Data.IORef+import Foreign.C.String+import Foreign.Ptr++import LLVM.Internal.Coding+import qualified LLVM.Internal.FFI.LLVMCTypes as FFI+import qualified LLVM.Internal.FFI.OrcJIT as FFI++newtype MangledSymbol = MangledSymbol ByteString+  deriving (Show, Eq, Ord)++instance EncodeM (AnyContT IO) MangledSymbol CString where+  encodeM (MangledSymbol bs) = anyContToM $ useAsCString bs++instance MonadIO m => DecodeM m MangledSymbol CString where+  decodeM str = liftIO $ MangledSymbol <$> packCString str++data JITSymbolFlags =+  JITSymbolFlags {+    jitSymbolWeak :: !Bool,+    jitSymbolExported :: !Bool+  }+  deriving (Show, Eq, Ord)++data JITSymbol =+  JITSymbol {+    jitSymbolAddress :: !WordPtr,+    jitSymbolFlags :: !JITSymbolFlags+  }+  deriving (Show, Eq, Ord)++type SymbolResolverFn = MangledSymbol -> IO JITSymbol++data SymbolResolver =+  SymbolResolver {+    dylibResolver :: !SymbolResolverFn,+    externalResolver :: !SymbolResolverFn+  }++newtype ObjectLinkingLayer = ObjectLinkingLayer (Ptr FFI.ObjectLinkingLayer)++instance Monad m => EncodeM m JITSymbolFlags FFI.JITSymbolFlags where+  encodeM f = return $ foldr1 (.|.) [+      if a f+         then b+         else 0+    | (a,b) <- [+          (jitSymbolWeak, FFI.jitSymbolFlagsWeak),+          (jitSymbolExported, FFI.jitSymbolFlagsExported)+        ]+    ]++instance Monad m => DecodeM m JITSymbolFlags FFI.JITSymbolFlags where+  decodeM f =+    return $ JITSymbolFlags {+      jitSymbolWeak = FFI.jitSymbolFlagsWeak .&. f /= 0,+      jitSymbolExported = FFI.jitSymbolFlagsExported .&. f /= 0+    }++instance MonadIO m => EncodeM m JITSymbol (Ptr FFI.JITSymbol -> IO ()) where+  encodeM (JITSymbol addr flags) = return $ \jitSymbol -> do+    flags' <- encodeM flags+    FFI.setJITSymbol jitSymbol (FFI.TargetAddress (fromIntegral addr)) flags'++instance MonadIO m => DecodeM m JITSymbol (Ptr FFI.JITSymbol) where+  decodeM jitSymbol = do+    FFI.TargetAddress addr <- liftIO $ FFI.getAddress jitSymbol+    flags <- liftIO $ decodeM =<< FFI.getFlags jitSymbol+    return (JITSymbol (fromIntegral addr) flags)++instance MonadIO m =>+  EncodeM m SymbolResolver (IORef [IO ()] -> IO (Ptr FFI.LambdaResolver)) where+  encodeM (SymbolResolver dylib external) = return $ \cleanups -> do+    dylib' <- allocFunPtr cleanups (encodeM dylib)+    external' <- allocFunPtr cleanups (encodeM external)+    FFI.createLambdaResolver dylib' external'++instance MonadIO m => EncodeM m SymbolResolverFn (FunPtr FFI.SymbolResolverFn) where+  encodeM callback =+    liftIO $ FFI.wrapSymbolResolverFn+      (\symbol result -> do+         setSymbol <- encodeM =<< callback =<< decodeM symbol+         setSymbol result)++-- | allocate a function pointer and register it for cleanup+allocFunPtr :: IORef [IO ()] -> IO (FunPtr a) -> IO (FunPtr a)+allocFunPtr cleanups alloc = mask $ \restore -> do+  funPtr <- restore alloc+  modifyIORef cleanups (freeHaskellFunPtr funPtr :)+  pure funPtr++withObjectLinkingLayer :: (ObjectLinkingLayer -> IO a) -> IO a+withObjectLinkingLayer f =+  bracket+    FFI.createObjectLinkingLayer+    FFI.disposeObjectLinkingLayer $ \objectLayer ->+      f (ObjectLinkingLayer objectLayer)
+ src/LLVM/Internal/OrcJIT/CompileOnDemandLayer.hs view
@@ -0,0 +1,146 @@+{-# LANGUAGE MultiParamTypeClasses #-}+module LLVM.Internal.OrcJIT.CompileOnDemandLayer where++import LLVM.Prelude++import Control.Exception+import Control.Monad.AnyCont+import Control.Monad.IO.Class+import Data.IORef+import Foreign.Marshal.Array+import Foreign.Ptr++import LLVM.Internal.Coding+import LLVM.Internal.Module+import LLVM.Internal.OrcJIT+import LLVM.Internal.OrcJIT.IRCompileLayer (IRCompileLayer(..))+import qualified LLVM.Internal.OrcJIT.IRCompileLayer as IRCompileLayer+import qualified LLVM.Internal.FFI.OrcJIT as FFI+import qualified LLVM.Internal.FFI.OrcJIT.CompileOnDemandLayer as FFI+import qualified LLVM.Internal.FFI.PtrHierarchy as FFI++type PartitioningFn = Ptr FFI.Function -> IO [Ptr FFI.Function]++newtype JITCompileCallbackManager =+  CallbackMgr (Ptr FFI.JITCompileCallbackManager)++newtype IndirectStubsManagerBuilder =+  StubsMgr (Ptr FFI.IndirectStubsManagerBuilder)++data CompileOnDemandLayer =+  CompileOnDemandLayer {+    compileLayer :: !(Ptr FFI.CompileOnDemandLayer),+    baseLayer :: !IRCompileLayer,+    cleanupActions :: !(IORef [IO ()])+  }+  deriving Eq++newtype ModuleSet = ModuleSet (Ptr FFI.ModuleSetHandle)++instance MonadIO m =>+  EncodeM m PartitioningFn (IORef [IO ()] -> IO (FunPtr FFI.PartitioningFn)) where+  encodeM partition = return $ \cleanups -> do+    allocFunPtr+      cleanups+      (FFI.wrapPartitioningFn+         (\f set -> do+           fs <- partition f+           traverse_ (FFI.insertFun set) fs+           return ()))++instance (MonadIO m, MonadAnyCont IO m) =>+  EncodeM m (Maybe (IO ())) FFI.TargetAddress where+  encodeM Nothing = return $ FFI.TargetAddress 0+  encodeM (Just f) = do+    f' <- anyContToM $ bracket (FFI.wrapErrorHandler f) freeHaskellFunPtr+    return . FFI.TargetAddress . fromIntegral . ptrToWordPtr . castFunPtrToPtr $ f'++withIndirectStubsManagerBuilder ::+  String {- ^ triple -} ->+  (IndirectStubsManagerBuilder -> IO a) ->+  IO a+withIndirectStubsManagerBuilder triple f = flip runAnyContT return $ do+  triple' <- encodeM triple+  stubsMgr <- anyContToM $ bracket+    (FFI.createLocalIndirectStubsManagerBuilder triple')+    FFI.disposeIndirectStubsManagerBuilder+  liftIO $ f (StubsMgr stubsMgr)++withJITCompileCallbackManager ::+  String {- ^ triple -} ->+  Maybe (IO ()) ->+  (JITCompileCallbackManager -> IO a) ->+  IO a+withJITCompileCallbackManager triple errorHandler f = flip runAnyContT return $ do+  triple' <- encodeM triple+  errorHandler' <- encodeM errorHandler+  callbackMgr <- anyContToM $ bracket+    (FFI.createLocalCompileCallbackManager triple' errorHandler')+    FFI.disposeCallbackManager+  liftIO $ f (CallbackMgr callbackMgr)++withCompileOnDemandLayer ::+  IRCompileLayer ->+  PartitioningFn ->+  JITCompileCallbackManager ->+  IndirectStubsManagerBuilder ->+  Bool ->+  (CompileOnDemandLayer -> IO a) ->+  IO a+withCompileOnDemandLayer+ baseLayer@(IRCompileLayer base _ _)+ partition+ (CallbackMgr callbackMgr)+ (StubsMgr stubsMgr)+ cloneStubsIntoPartitions+ f+ = flip runAnyContT return $ do+ cleanup <- anyContToM $ bracket (newIORef []) (sequence <=< readIORef)+ partitionAct <- encodeM partition+ partition' <- liftIO $ partitionAct cleanup+ cloneStubsIntoPartitions' <- encodeM cloneStubsIntoPartitions+ cl <- anyContToM $ bracket+         (FFI.createCompileOnDemandLayer+            base+            partition'+            callbackMgr+            stubsMgr+            cloneStubsIntoPartitions')+         FFI.disposeCompileOnDemandLayer+ liftIO $ f (CompileOnDemandLayer cl baseLayer cleanup)++mangleSymbol :: CompileOnDemandLayer -> String -> IO MangledSymbol+mangleSymbol (CompileOnDemandLayer _ bl _) symbol =+  IRCompileLayer.mangleSymbol bl symbol++findSymbol :: CompileOnDemandLayer -> MangledSymbol -> Bool -> IO JITSymbol+findSymbol (CompileOnDemandLayer cl _ _) symbol exportedSymbolsOnly = flip runAnyContT return $ do+  symbol' <- encodeM symbol+  exportedSymbolsOnly' <- encodeM exportedSymbolsOnly+  symbol <- anyContToM $ bracket+    (FFI.findSymbol cl symbol' exportedSymbolsOnly') FFI.disposeSymbol+  decodeM symbol++addModuleSet :: CompileOnDemandLayer -> [Module] -> SymbolResolver -> IO ModuleSet+addModuleSet+  (CompileOnDemandLayer cl (IRCompileLayer _ dl _) cleanups)+  modules+  resolver+  = flip runAnyContT return $ do+  resolverAct <- encodeM resolver+  resolver' <- liftIO $ resolverAct cleanups+  modules' <- liftIO $ mapM readModule modules+  (moduleCount, modules'') <-+    anyContToM $ \f -> withArrayLen modules' $ \n hs -> f (fromIntegral n, hs)+  moduleSet <- liftIO $ FFI.addModuleSet cl dl modules'' moduleCount resolver'+  pure (ModuleSet moduleSet)++removeModuleSet :: CompileOnDemandLayer -> ModuleSet -> IO ()+removeModuleSet (CompileOnDemandLayer cl _ _) (ModuleSet handle) =+  FFI.removeModuleSet cl handle++withModuleSet :: CompileOnDemandLayer -> [Module] -> SymbolResolver -> (ModuleSet -> IO a) -> IO a+withModuleSet compileLayer modules resolver =+  bracket+    (addModuleSet compileLayer modules resolver)+    (removeModuleSet compileLayer)
+ src/LLVM/Internal/OrcJIT/IRCompileLayer.hs view
@@ -0,0 +1,74 @@+{-# LANGUAGE MultiParamTypeClasses #-}+module LLVM.Internal.OrcJIT.IRCompileLayer where++import LLVM.Prelude++import Control.Exception+import Control.Monad.AnyCont+import Control.Monad.IO.Class+import Data.IORef+import Foreign.Marshal.Array (withArrayLen)+import Foreign.Ptr++import LLVM.Internal.Coding+import qualified LLVM.Internal.FFI.DataLayout as FFI+import qualified LLVM.Internal.FFI.OrcJIT as FFI+import qualified LLVM.Internal.FFI.OrcJIT.IRCompileLayer as FFI+import qualified LLVM.Internal.FFI.Target as FFI+import LLVM.Internal.Module+import LLVM.Internal.OrcJIT+import LLVM.Internal.Target++data IRCompileLayer =+  IRCompileLayer {+    compileLayer :: !(Ptr FFI.IRCompileLayer),+    dataLayout :: !(Ptr FFI.DataLayout),+    cleanupActions :: !(IORef [IO ()])+  }+  deriving Eq++newtype ModuleSet = ModuleSet (Ptr FFI.ModuleSetHandle)++withIRCompileLayer :: ObjectLinkingLayer -> TargetMachine -> (IRCompileLayer -> IO a) -> IO a+withIRCompileLayer (ObjectLinkingLayer oll) (TargetMachine tm) f = flip runAnyContT return $ do+  dl <- anyContToM $ bracket (FFI.createTargetDataLayout tm) FFI.disposeDataLayout+  cl <- anyContToM $ bracket (FFI.createIRCompileLayer oll tm) FFI.disposeIRCompileLayer+  cleanup <- anyContToM $ bracket (newIORef []) (sequence <=< readIORef)+  liftIO $ f (IRCompileLayer cl dl cleanup)++mangleSymbol :: IRCompileLayer -> String -> IO MangledSymbol+mangleSymbol (IRCompileLayer _ dl _) symbol = flip runAnyContT return $ do+  mangledSymbol <- alloca+  symbol' <- encodeM symbol+  anyContToM $ bracket+    (FFI.getMangledSymbol mangledSymbol symbol' dl)+    (\_ -> FFI.disposeMangledSymbol =<< peek mangledSymbol)+  decodeM =<< peek mangledSymbol++findSymbol :: IRCompileLayer -> MangledSymbol -> Bool -> IO JITSymbol+findSymbol (IRCompileLayer cl _ _) symbol exportedSymbolsOnly = flip runAnyContT return $ do+  symbol' <- encodeM symbol+  exportedSymbolsOnly' <- encodeM exportedSymbolsOnly+  symbol <- anyContToM $ bracket+    (FFI.findSymbol cl symbol' exportedSymbolsOnly') FFI.disposeSymbol+  decodeM symbol++addModuleSet :: IRCompileLayer -> [Module] -> SymbolResolver -> IO ModuleSet+addModuleSet (IRCompileLayer cl dl cleanups) modules resolver = flip runAnyContT return $ do+  resolverAct <- encodeM resolver+  resolver' <- liftIO $ resolverAct cleanups+  modules' <- liftIO $ mapM readModule modules+  (moduleCount, modules'') <-+    anyContToM $ \f -> withArrayLen modules' $ \n hs -> f (fromIntegral n, hs)+  moduleSet <- liftIO $ FFI.addModuleSet cl dl modules'' moduleCount resolver'+  pure (ModuleSet moduleSet)++removeModuleSet :: IRCompileLayer -> ModuleSet -> IO ()+removeModuleSet (IRCompileLayer cl _ _) (ModuleSet handle) =+  FFI.removeModuleSet cl handle++withModuleSet :: IRCompileLayer -> [Module] -> SymbolResolver -> (ModuleSet -> IO a) -> IO a+withModuleSet compileLayer modules resolver =+  bracket+    (addModuleSet compileLayer modules resolver)+    (removeModuleSet compileLayer)
+ src/LLVM/Internal/PassManager.hs view
@@ -0,0 +1,147 @@+{-# LANGUAGE+  TemplateHaskell,+  MultiParamTypeClasses,+  CPP+  #-}+module LLVM.Internal.PassManager where++import LLVM.Prelude++import qualified Language.Haskell.TH as TH++import Control.Exception+import Control.Monad.IO.Class++import Control.Monad.AnyCont++import Foreign.C (CString)+import Foreign.Ptr++import qualified LLVM.Internal.FFI.PassManager as FFI+import qualified LLVM.Internal.FFI.Transforms as FFI++import LLVM.Internal.Module+import LLVM.Internal.Target+import LLVM.Internal.Coding+import LLVM.Transforms++import LLVM.AST.DataLayout++-- | <http://llvm.org/doxygen/classllvm_1_1PassManager.html>+-- Note: a PassManager does substantive behind-the-scenes work, arranging for the+-- results of various analyses to be available as needed by transform passes, shared+-- as possible.+newtype PassManager = PassManager (Ptr FFI.PassManager)++-- | There are different ways to get a 'PassManager'. This type embodies them.+data PassSetSpec+  -- | a 'PassSetSpec' is a lower-level, detailed specification of a set of passes. It+  -- allows fine-grained control of what passes are to be run when, and the specification+  -- of passes not available through 'CuratedPassSetSpec'.+  = PassSetSpec {+      transforms :: [Pass],+      dataLayout :: Maybe DataLayout,+      targetLibraryInfo :: Maybe TargetLibraryInfo,+      targetMachine :: Maybe TargetMachine+    }+  -- | This type is a high-level specification of a set of passes. It uses the same+  -- collection of passes chosen by the LLVM team in the command line tool 'opt'.  The fields+  -- of this spec are much like typical compiler command-line flags - e.g. -O\<n\>, etc.+  | CuratedPassSetSpec {+      optLevel :: Maybe Word,+      sizeLevel :: Maybe Word,+      unitAtATime :: Maybe Bool,+      simplifyLibCalls :: Maybe Bool,+      loopVectorize :: Maybe Bool,+      superwordLevelParallelismVectorize :: Maybe Bool,+      useInlinerWithThreshold :: Maybe Word,+      dataLayout :: Maybe DataLayout,+      targetLibraryInfo :: Maybe TargetLibraryInfo,+      targetMachine :: Maybe TargetMachine+    }++-- | Helper to make a curated 'PassSetSpec'+defaultCuratedPassSetSpec :: PassSetSpec+defaultCuratedPassSetSpec = CuratedPassSetSpec {+  optLevel = Nothing,+  sizeLevel = Nothing,+  unitAtATime = Nothing,+  simplifyLibCalls = Nothing,+  loopVectorize = Nothing,+  superwordLevelParallelismVectorize = Nothing,+  useInlinerWithThreshold = Nothing,+  dataLayout = Nothing,+  targetLibraryInfo = Nothing,+  targetMachine = Nothing+}++-- | an empty 'PassSetSpec'+defaultPassSetSpec :: PassSetSpec+defaultPassSetSpec = PassSetSpec {+  transforms = [],+  dataLayout = Nothing,+  targetLibraryInfo = Nothing,+  targetMachine = Nothing+}++instance (Monad m, MonadAnyCont IO m) => EncodeM m GCOVVersion CString where+  encodeM (GCOVVersion cs@[_,_,_,_]) = encodeM cs++createPassManager :: PassSetSpec -> IO (Ptr FFI.PassManager)+createPassManager pss = flip runAnyContT return $ do+  pm <- liftIO $ FFI.createPassManager+  forM_ (targetLibraryInfo pss) $ \(TargetLibraryInfo tli) -> do+    liftIO $ FFI.addTargetLibraryInfoPass pm tli+  forM_ (targetMachine pss) $ \(TargetMachine tm) -> liftIO $ FFI.addAnalysisPasses tm pm+  case pss of+    s@CuratedPassSetSpec {} -> liftIO $ do+      bracket FFI.passManagerBuilderCreate FFI.passManagerBuilderDispose $ \b -> do+        let handleOption g m = forM_ (m s) (g b <=< encodeM) +        handleOption FFI.passManagerBuilderSetOptLevel optLevel+        handleOption FFI.passManagerBuilderSetSizeLevel sizeLevel+        handleOption FFI.passManagerBuilderSetDisableUnitAtATime (liftM not . unitAtATime)+        handleOption FFI.passManagerBuilderSetDisableSimplifyLibCalls (liftM not . simplifyLibCalls)+        handleOption FFI.passManagerBuilderUseInlinerWithThreshold useInlinerWithThreshold+        handleOption FFI.passManagerBuilderSetLoopVectorize loopVectorize+        handleOption FFI.passManagerBuilderSetSuperwordLevelParallelismVectorize superwordLevelParallelismVectorize+        FFI.passManagerBuilderPopulateModulePassManager b pm+    PassSetSpec ps dl tli tm' -> do+      let tm = maybe nullPtr (\(TargetMachine tm) -> tm) tm'+      forM_ ps $ \p -> $(+        do+#if __GLASGOW_HASKELL__ < 800+          TH.TyConI (TH.DataD _ _ _ cons _) <- TH.reify ''Pass+#else+          TH.TyConI (TH.DataD _ _ _ _ cons _) <- TH.reify ''Pass+#endif+          TH.caseE [| p |] $ flip map cons $ \con -> do+            let+              (n, fns) = case con of+                            TH.RecC n fs -> (n, [ TH.nameBase fn | (fn, _, _) <- fs ])+                            TH.NormalC n [] -> (n, [])+              actions = +                [ TH.bindS (TH.varP . TH.mkName $ fn) [| encodeM $(TH.dyn fn) |] | fn <- fns ]+                ++ [+                 TH.noBindS [|+                   liftIO $(+                     foldl1 TH.appE+                     (map TH.dyn $+                        ["FFI.add" ++ TH.nameBase n ++ "Pass", "pm"]+                        ++ ["tm" | FFI.needsTargetMachine (TH.nameBase n)]+                        ++ fns)+                    )+                   |]+                 ]+            TH.match (TH.conP n $ map (TH.varP . TH.mkName) fns) (TH.normalB (TH.doE actions)) []+       )+  return pm++-- | bracket the creation of a 'PassManager'+withPassManager :: PassSetSpec -> (PassManager -> IO a) -> IO a+withPassManager s = bracket (createPassManager s) FFI.disposePassManager . (. PassManager)++-- | run the passes in a 'PassManager' on a 'Module', modifying the 'Module'.+runPassManager :: PassManager -> Module -> IO Bool+runPassManager (PassManager p) m = do+  m' <- readModule m+  toEnum . fromIntegral <$> FFI.runPassManager p m'
+ src/LLVM/Internal/RMWOperation.hs view
@@ -0,0 +1,25 @@+{-# LANGUAGE+  TemplateHaskell,+  MultiParamTypeClasses+  #-}+module LLVM.Internal.RMWOperation where++import LLVM.AST.RMWOperation++import qualified LLVM.Internal.FFI.LLVMCTypes as FFI++import LLVM.Internal.Coding++genCodingInstance [t| RMWOperation |] ''FFI.RMWOperation [+  (FFI.rmwOperationXchg, Xchg),+  (FFI.rmwOperationAdd, Add),+  (FFI.rmwOperationSub, Sub),+  (FFI.rmwOperationAnd, And),+  (FFI.rmwOperationNand, Nand),+  (FFI.rmwOperationOr, Or),+  (FFI.rmwOperationXor, Xor),+  (FFI.rmwOperationMax, Max),+  (FFI.rmwOperationMin, Min),+  (FFI.rmwOperationUMax, UMax),+  (FFI.rmwOperationUMin, UMin)+ ]
+ src/LLVM/Internal/RawOStream.hs view
@@ -0,0 +1,79 @@+module LLVM.Internal.RawOStream where++import LLVM.Prelude++import Control.Monad.AnyCont+import Control.Monad.Error.Class+import Control.Monad.IO.Class+import Control.Monad.Trans.Except++import Data.IORef+import Foreign.C+import Foreign.Ptr++import qualified LLVM.Internal.FFI.RawOStream as FFI+import qualified LLVM.Internal.FFI.PtrHierarchy as FFI++import LLVM.Internal.Coding+import LLVM.Internal.Inject+import LLVM.Internal.String ()++withFileRawOStream ::+  (Inject String e, MonadError e m, MonadAnyCont IO m, MonadIO m)+  => String+  -> Bool+  -> Bool+  -> (Ptr FFI.RawOStream -> ExceptT String IO ())+  -> m ()+withFileRawOStream path excl text c =+  withFileRawPWriteStream path excl text (c . FFI.upCast)++withFileRawPWriteStream ::+  (Inject String e, MonadError e m, MonadAnyCont IO m, MonadIO m)+  => String+  -> Bool+  -> Bool+  -> (Ptr FFI.RawPWriteStream -> ExceptT String IO ())+  -> m ()+withFileRawPWriteStream path excl text c = do+  path <- encodeM path+  excl <- encodeM excl+  text <- encodeM text+  msgPtr <- alloca+  errorRef <- liftIO $ newIORef undefined+  succeeded <- decodeM =<< (liftIO $ FFI.withFileRawPWriteStream path excl text msgPtr $ \os -> do+                              r <- runExceptT (c os)+                              writeIORef errorRef r)+  unless succeeded $ do+    s <- decodeM msgPtr+    throwError $ inject (s :: String)+  e <- liftIO $ readIORef errorRef+  either (throwError . inject) return e++withBufferRawOStream ::+  (Inject String e, MonadError e m, MonadIO m, DecodeM IO a (Ptr CChar, CSize))+  => (Ptr FFI.RawOStream -> ExceptT String IO ())+  -> m a+withBufferRawOStream c = withBufferRawPWriteStream (c . FFI.upCast)++withBufferRawPWriteStream ::+  (Inject String e, MonadError e m, MonadIO m, DecodeM IO a (Ptr CChar, CSize))+  => (Ptr FFI.RawPWriteStream -> ExceptT String IO ())+  -> m a+withBufferRawPWriteStream c = do+  resultRef <- liftIO $ newIORef Nothing+  errorRef <- liftIO $ newIORef undefined+  let saveBuffer :: Ptr CChar -> CSize -> IO ()+      saveBuffer start size = do+        r <- decodeM (start, size)+        writeIORef resultRef (Just r)+      saveError os = do+        r <- runExceptT (c os)+        writeIORef errorRef r+  liftIO $ FFI.withBufferRawPWriteStream saveBuffer saveError+  e <- liftIO $ readIORef errorRef+  case e of+    Left e -> throwError $ inject e+    _ -> do+      Just r <- liftIO $ readIORef resultRef+      return r
+ src/LLVM/Internal/String.hs view
@@ -0,0 +1,61 @@+{-# LANGUAGE+  MultiParamTypeClasses,+  UndecidableInstances+  #-}+module LLVM.Internal.String where++import LLVM.Prelude++import Control.Arrow+import Control.Monad.AnyCont+import Control.Monad.IO.Class+import Control.Exception (finally)+import Data.Maybe (fromMaybe)+import Foreign.C (CString, CChar)+import Foreign.Ptr+import Foreign.Storable (Storable)+import Foreign.Marshal.Alloc as F.M (alloca, free)++import LLVM.Internal.FFI.LLVMCTypes++import LLVM.Internal.Coding++import qualified Data.ByteString as BS+import qualified Data.ByteString.Unsafe as BS+import qualified Data.ByteString.UTF8 as BSUTF8++newtype UTF8ByteString = UTF8ByteString { utf8Bytes :: BS.ByteString }++instance (Monad e) => EncodeM e String UTF8ByteString where+  encodeM = return . UTF8ByteString . BSUTF8.fromString++instance (Monad d) => DecodeM d String UTF8ByteString where+  decodeM = return . BSUTF8.toString . utf8Bytes++instance (MonadAnyCont IO e) => EncodeM e String CString where+  encodeM s = anyContToM (BS.unsafeUseAsCString . utf8Bytes =<< encodeM (s ++ "\0"))++instance (Integral i, MonadAnyCont IO e) => EncodeM e String (Ptr CChar, i) where+  encodeM s = anyContToM ((. (. second fromIntegral)) $ BS.useAsCStringLen . utf8Bytes =<< encodeM s)++instance (MonadIO d) => DecodeM d String CString where+  decodeM = decodeM . UTF8ByteString <=< liftIO . BS.packCString++instance (MonadIO d) => DecodeM d String (OwnerTransfered CString) where+  decodeM (OwnerTransfered s) = liftIO $ finally (decodeM s) (free s)++instance (MonadIO d) => DecodeM d String (Ptr (OwnerTransfered CString)) where+  decodeM = liftIO . decodeM <=< peek++instance (Integral i, MonadIO d) => DecodeM d String (Ptr CChar, i) where+  decodeM = decodeM . UTF8ByteString <=< liftIO . BS.packCStringLen . second fromIntegral++instance (Integral i, MonadIO d) => DecodeM d BS.ByteString (Ptr CChar, i) where+  decodeM = liftIO . BS.packCStringLen . second fromIntegral++instance (Integral i, Storable i, MonadIO d) => DecodeM d String (Ptr i -> IO (Ptr CChar)) where+  decodeM f = decodeM =<< (liftIO $ F.M.alloca $ \p -> (,) `liftM` f p `ap` peek p)++instance (Monad e, EncodeM e String c) => EncodeM e (Maybe String) (NothingAsEmptyString c) where+  encodeM = liftM NothingAsEmptyString . encodeM . fromMaybe ""+  
+ src/LLVM/Internal/TailCallKind.hs view
@@ -0,0 +1,18 @@+{-# LANGUAGE+  TemplateHaskell,+  MultiParamTypeClasses+  #-}+module LLVM.Internal.TailCallKind where++import LLVM.Prelude++import qualified LLVM.Internal.FFI.LLVMCTypes as FFI++import LLVM.Internal.Coding+import qualified LLVM.AST as A++genCodingInstance [t| Maybe A.TailCallKind |] ''FFI.TailCallKind [+  (FFI.tailCallKindNone, Nothing),+  (FFI.tailCallKindTail, Just A.Tail),+  (FFI.tailCallKindMustTail, Just A.MustTail)+ ]
+ src/LLVM/Internal/Target.hs view
@@ -0,0 +1,314 @@+{-# LANGUAGE+  TemplateHaskell,+  MultiParamTypeClasses,+  RecordWildCards,+  UndecidableInstances+  #-}+module LLVM.Internal.Target where++import LLVM.Prelude++import Control.Exception+import Control.Monad.AnyCont+import Control.Monad.Error.Class+import Control.Monad.IO.Class+import Control.Monad.Trans.Except++import Foreign.Ptr+import Foreign.C.String+import Data.List (intercalate)+import Data.Map (Map)+import qualified Data.Map as Map++import Text.ParserCombinators.Parsec hiding (many)++import LLVM.Internal.Coding+import LLVM.Internal.String ()+import LLVM.Internal.LibraryFunction+import LLVM.DataLayout++import LLVM.AST.DataLayout++import qualified LLVM.Internal.FFI.LLVMCTypes as FFI+import qualified LLVM.Internal.FFI.Target as FFI++import qualified LLVM.Relocation as Reloc+import qualified LLVM.Target.Options as TO+import qualified LLVM.CodeModel as CodeModel+import qualified LLVM.CodeGenOpt as CodeGenOpt++genCodingInstance [t| Reloc.Model |] ''FFI.RelocModel [+  (FFI.relocModelDefault, Reloc.Default),+  (FFI.relocModelStatic, Reloc.Static),+  (FFI.relocModelPIC, Reloc.PIC),+  (FFI.relocModelDynamicNoPic, Reloc.DynamicNoPIC)+ ]++genCodingInstance [t| CodeModel.Model |] ''FFI.CodeModel [+  (FFI.codeModelDefault,CodeModel.Default),+  (FFI.codeModelJITDefault, CodeModel.JITDefault),+  (FFI.codeModelSmall, CodeModel.Small),+  (FFI.codeModelKernel, CodeModel.Kernel),+  (FFI.codeModelMedium, CodeModel.Medium),+  (FFI.codeModelLarge, CodeModel.Large)+ ]++genCodingInstance [t| CodeGenOpt.Level |] ''FFI.CodeGenOptLevel [+  (FFI.codeGenOptLevelNone, CodeGenOpt.None),+  (FFI.codeGenOptLevelLess, CodeGenOpt.Less),+  (FFI.codeGenOptLevelDefault, CodeGenOpt.Default),+  (FFI.codeGenOptLevelAggressive, CodeGenOpt.Aggressive)+ ]++genCodingInstance [t| TO.FloatABI |] ''FFI.FloatABIType [+  (FFI.floatABIDefault, TO.FloatABIDefault),+  (FFI.floatABISoft, TO.FloatABISoft),+  (FFI.floatABIHard, TO.FloatABIHard)+ ]++genCodingInstance [t| TO.FloatingPointOperationFusionMode |] ''FFI.FPOpFusionMode [+  (FFI.fpOpFusionModeFast, TO.FloatingPointOperationFusionFast),+  (FFI.fpOpFusionModeStandard, TO.FloatingPointOperationFusionStandard),+  (FFI.fpOpFusionModeStrict, TO.FloatingPointOperationFusionStrict)+ ]++-- | <http://llvm.org/doxygen/classllvm_1_1Target.html>+newtype Target = Target (Ptr FFI.Target)++-- | e.g. an instruction set extension+newtype CPUFeature = CPUFeature String+  deriving (Eq, Ord, Read, Show)++instance EncodeM e String es => EncodeM e (Map CPUFeature Bool) es where+  encodeM = encodeM . intercalate "," . map (\(CPUFeature f, enabled) -> (if enabled then "+" else "-") ++ f) . Map.toList++instance (Monad d, DecodeM d String es) => DecodeM d (Map CPUFeature Bool) es where+  decodeM es = do+    s <- decodeM es+    let flag = do+          en <- choice [char '-' >> return False, char '+' >> return True]+          s <- many1 (noneOf ",")+          return (CPUFeature s, en)+        features = liftM Map.fromList (flag `sepBy` (char ','))+    case parse (do f <- features; eof; return f) "CPU Feature string" (s :: String) of+      Right features -> return features+      Left _ -> fail "failure to parse CPUFeature string"+                       +-- | Find a 'Target' given an architecture and/or a \"triple\".+-- | <http://llvm.org/doxygen/structllvm_1_1TargetRegistry.html#a3105b45e546c9cc3cf78d0f2ec18ad89>+-- | Be sure to run either 'initializeAllTargets' or 'initializeNativeTarget' before expecting this to succeed, depending on what target(s) you want to use.+lookupTarget ::+  Maybe String -- ^ arch+  -> String -- ^ \"triple\" - e.g. x86_64-unknown-linux-gnu+  -> ExceptT String IO (Target, String)+lookupTarget arch triple = flip runAnyContT return $ do+  cErrorP <- alloca+  cNewTripleP <- alloca+  arch <- encodeM (maybe "" id arch)+  triple <- encodeM triple+  target <- liftIO $ FFI.lookupTarget arch triple cNewTripleP cErrorP+  when (target == nullPtr) $ throwError =<< decodeM cErrorP+  liftM (Target target, ) $ decodeM cNewTripleP++-- | <http://llvm.org/doxygen/classllvm_1_1TargetOptions.html>+newtype TargetOptions = TargetOptions (Ptr FFI.TargetOptions)++-- | bracket creation and destruction of a 'TargetOptions' object+withTargetOptions :: (TargetOptions -> IO a) -> IO a+withTargetOptions = bracket FFI.createTargetOptions FFI.disposeTargetOptions . (. TargetOptions)++-- | set all target options+pokeTargetOptions :: TO.Options -> TargetOptions -> IO ()+pokeTargetOptions hOpts (TargetOptions cOpts) = do+  mapM_ (\(c, ha) -> FFI.setTargetOptionFlag cOpts c =<< encodeM (ha hOpts)) [+    (FFI.targetOptionFlagPrintMachineCode, TO.printMachineCode),+    (FFI.targetOptionFlagLessPreciseFPMADOption, TO.lessPreciseFloatingPointMultiplyAddOption),+    (FFI.targetOptionFlagUnsafeFPMath, TO.unsafeFloatingPointMath),+    (FFI.targetOptionFlagNoInfsFPMath, TO.noInfinitiesFloatingPointMath),+    (FFI.targetOptionFlagNoNaNsFPMath, TO.noNaNsFloatingPointMath),+    (FFI.targetOptionFlagHonorSignDependentRoundingFPMathOption, TO.honorSignDependentRoundingFloatingPointMathOption),+    (FFI.targetOptionFlagNoZerosInBSS, TO.noZerosInBSS),+    (FFI.targetOptionFlagGuaranteedTailCallOpt, TO.guaranteedTailCallOptimization),+    (FFI.targetOptionFlagEnableFastISel, TO.enableFastInstructionSelection),+    (FFI.targetOptionFlagUseInitArray, TO.useInitArray),+    (FFI.targetOptionFlagDisableIntegratedAS, TO.disableIntegratedAssembler),+    (FFI.targetOptionFlagCompressDebugSections, TO.compressDebugSections),+    (FFI.targetOptionFlagTrapUnreachable, TO.trapUnreachable)+   ]+  FFI.setStackAlignmentOverride cOpts =<< encodeM (TO.stackAlignmentOverride hOpts)+  FFI.setFloatABIType cOpts =<< encodeM (TO.floatABIType hOpts)+  FFI.setAllowFPOpFusion cOpts =<< encodeM (TO.allowFloatingPointOperationFusion hOpts)++-- | get all target options+peekTargetOptions :: TargetOptions -> IO TO.Options+peekTargetOptions (TargetOptions tOpts) = do+  let gof = decodeM <=< FFI.getTargetOptionsFlag tOpts+  printMachineCode+    <- gof FFI.targetOptionFlagPrintMachineCode+  lessPreciseFloatingPointMultiplyAddOption+    <- gof FFI.targetOptionFlagLessPreciseFPMADOption+  unsafeFloatingPointMath+    <- gof FFI.targetOptionFlagUnsafeFPMath+  noInfinitiesFloatingPointMath+    <- gof FFI.targetOptionFlagNoInfsFPMath+  noNaNsFloatingPointMath+    <- gof FFI.targetOptionFlagNoNaNsFPMath+  honorSignDependentRoundingFloatingPointMathOption+    <- gof FFI.targetOptionFlagHonorSignDependentRoundingFPMathOption+  noZerosInBSS+    <- gof FFI.targetOptionFlagNoZerosInBSS+  guaranteedTailCallOptimization+    <- gof FFI.targetOptionFlagGuaranteedTailCallOpt+  enableFastInstructionSelection+    <- gof FFI.targetOptionFlagEnableFastISel+  useInitArray+    <- gof FFI.targetOptionFlagUseInitArray+  disableIntegratedAssembler+    <- gof FFI.targetOptionFlagDisableIntegratedAS+  compressDebugSections+    <- gof FFI.targetOptionFlagCompressDebugSections+  trapUnreachable+    <- gof FFI.targetOptionFlagTrapUnreachable+  stackAlignmentOverride <- decodeM =<< FFI.getStackAlignmentOverride tOpts+  floatABIType <- decodeM =<< FFI.getFloatABIType tOpts+  allowFloatingPointOperationFusion <- decodeM =<< FFI.getAllowFPOpFusion tOpts+  return TO.Options { .. }++-- | <http://llvm.org/doxygen/classllvm_1_1TargetMachine.html>+newtype TargetMachine = TargetMachine (Ptr FFI.TargetMachine)++-- | bracket creation and destruction of a 'TargetMachine'+withTargetMachine ::+    Target+    -> String -- ^ triple+    -> String -- ^ cpu+    -> Map CPUFeature Bool -- ^ features+    -> TargetOptions+    -> Reloc.Model+    -> CodeModel.Model+    -> CodeGenOpt.Level+    -> (TargetMachine -> IO a)+    -> IO a+withTargetMachine+  (Target target)+  triple+  cpu+  features+  (TargetOptions targetOptions)+  relocModel+  codeModel+  codeGenOptLevel = runAnyContT $ do+  triple <- encodeM triple+  cpu <- encodeM cpu+  features <- encodeM features+  relocModel <- encodeM relocModel+  codeModel <- encodeM codeModel+  codeGenOptLevel <- encodeM codeGenOptLevel+  anyContToM $ bracket (+      FFI.createTargetMachine+         target+         triple+         cpu+         features+         targetOptions+         relocModel+         codeModel+         codeGenOptLevel+      )+      FFI.disposeTargetMachine+      . (. TargetMachine)++-- | <http://llvm.org/doxygen/classllvm_1_1TargetLowering.html>+newtype TargetLowering = TargetLowering (Ptr FFI.TargetLowering)++-- | get the 'TargetLowering' of a 'TargetMachine'+getTargetLowering :: TargetMachine -> IO TargetLowering+getTargetLowering (TargetMachine tm) = TargetLowering <$> error "FIXME: getTargetLowering" -- FFI.getTargetLowering tm++-- | Initialize the native target. This function is called automatically in these Haskell bindings+-- when creating an 'LLVM.ExecutionEngine.ExecutionEngine' which will require it, and so it should+-- not be necessary to call it separately.+initializeNativeTarget :: IO ()+initializeNativeTarget = do+  failure <- decodeM =<< liftIO FFI.initializeNativeTarget+  when failure $ fail "native target initialization failed"++-- | the target triple corresponding to the target machine+getTargetMachineTriple :: TargetMachine -> IO String+getTargetMachineTriple (TargetMachine m) = decodeM =<< FFI.getTargetMachineTriple m++-- | the default target triple that LLVM has been configured to produce code for+getDefaultTargetTriple :: IO String+getDefaultTargetTriple = decodeM =<< FFI.getDefaultTargetTriple++-- | a target triple suitable for loading code into the current process+getProcessTargetTriple :: IO String+getProcessTargetTriple = decodeM =<< FFI.getProcessTargetTriple++-- | the LLVM name for the host CPU+getHostCPUName :: IO String+getHostCPUName = decodeM FFI.getHostCPUName++-- | a space-separated list of LLVM feature names supported by the host CPU+getHostCPUFeatures :: IO (Map CPUFeature Bool)+getHostCPUFeatures =+  decodeM =<< FFI.getHostCPUFeatures++-- | 'DataLayout' to use for the given 'TargetMachine'+getTargetMachineDataLayout :: TargetMachine -> IO DataLayout+getTargetMachineDataLayout (TargetMachine m) = do+  dlString <- decodeM =<< FFI.getTargetMachineDataLayout m+  let Right (Just dl) = runExcept . parseDataLayout BigEndian $ dlString+  return dl++-- | Initialize all targets so they can be found by 'lookupTarget'+initializeAllTargets :: IO ()+initializeAllTargets = FFI.initializeAllTargets++-- | Bracket creation and destruction of a 'TargetMachine' configured for the host+withHostTargetMachine :: (TargetMachine -> IO a) -> ExceptT String IO a+withHostTargetMachine f = do+  liftIO $ initializeAllTargets+  triple <- liftIO $ getProcessTargetTriple+  cpu <- liftIO $ getHostCPUName+  features <- liftIO $ getHostCPUFeatures+  (target, _) <- lookupTarget Nothing triple+  liftIO $ withTargetOptions $ \options ->+      withTargetMachine target triple cpu features options Reloc.Default CodeModel.Default CodeGenOpt.Default f++-- | <http://llvm.org/docs/doxygen/html/classllvm_1_1TargetLibraryInfo.html>+newtype TargetLibraryInfo = TargetLibraryInfo (Ptr FFI.TargetLibraryInfo)++-- | Look up a 'LibraryFunction' by its standard name+getLibraryFunction :: TargetLibraryInfo -> String -> IO (Maybe LibraryFunction)+getLibraryFunction (TargetLibraryInfo f) name = flip runAnyContT return $ do+  libFuncP <- alloca :: AnyContT IO (Ptr FFI.LibFunc)+  name <- (encodeM name :: AnyContT IO CString)+  r <- decodeM =<< (liftIO $ FFI.getLibFunc f name libFuncP)+  forM (if r then Just libFuncP else Nothing) $ decodeM <=< peek++-- | Get a the current name to be emitted for a 'LibraryFunction'+getLibraryFunctionName :: TargetLibraryInfo -> LibraryFunction -> IO String+getLibraryFunctionName (TargetLibraryInfo f) l = flip runAnyContT return $ do+  l <- encodeM l+  decodeM $ FFI.libFuncGetName f l++-- | Set the name of the function on the target platform that corresponds to funcName+setLibraryFunctionAvailableWithName ::+  TargetLibraryInfo+  -> LibraryFunction+  -> String -- ^ The function name to be emitted+  -> IO ()+setLibraryFunctionAvailableWithName (TargetLibraryInfo f) libraryFunction name = flip runAnyContT return $ do+  name <- encodeM name+  libraryFunction <- encodeM libraryFunction+  liftIO $ FFI.libFuncSetAvailableWithName f libraryFunction name++-- | look up information about the library functions available on a given platform+withTargetLibraryInfo ::+  String -- ^ triple+  -> (TargetLibraryInfo -> IO a)+  -> IO a+withTargetLibraryInfo triple f = flip runAnyContT return $ do+  triple <- encodeM triple+  liftIO $ bracket (FFI.createTargetLibraryInfo triple) FFI.disposeTargetLibraryInfo (f . TargetLibraryInfo)
+ src/LLVM/Internal/Threading.hs view
@@ -0,0 +1,13 @@+module LLVM.Internal.Threading (+  isMultithreaded+  ) where++import LLVM.Prelude++import qualified LLVM.Internal.FFI.Threading as FFI++import LLVM.Internal.Coding++-- | Check if multithreading is enabled in LLVM+isMultithreaded :: IO Bool+isMultithreaded = FFI.isMultithreaded >>= decodeM
+ src/LLVM/Internal/Type.hs view
@@ -0,0 +1,164 @@+{-# LANGUAGE+  QuasiQuotes,+  MultiParamTypeClasses+  #-}+module LLVM.Internal.Type where++import LLVM.Prelude++import Control.Monad.AnyCont+import Control.Monad.Error.Class+import Control.Monad.State++import qualified Data.Set as Set++import Foreign.Ptr++import qualified LLVM.Internal.FFI.LLVMCTypes as FFI+import LLVM.Internal.FFI.LLVMCTypes (typeKindP)+import qualified LLVM.Internal.FFI.Type as FFI+import qualified LLVM.Internal.FFI.PtrHierarchy as FFI++import qualified LLVM.AST as A+import qualified LLVM.AST.AddrSpace as A++import LLVM.Internal.Context+import LLVM.Internal.Coding+import LLVM.Internal.DecodeAST+import LLVM.Internal.EncodeAST++getStructure :: Ptr FFI.Type -> DecodeAST A.Type+getStructure t = scopeAnyCont $ do+  return A.StructureType+   `ap` (decodeM =<< liftIO (FFI.isPackedStruct t))+   `ap` do+       n <- liftIO (FFI.countStructElementTypes t)+       ts <- allocaArray n+       liftIO $ FFI.getStructElementTypes t ts+       decodeM (n, ts)++getStructDefinitions :: DecodeAST [A.Definition]+getStructDefinitions = do+  let getStructDefinition t = do+       opaque <- decodeM =<< liftIO (FFI.structIsOpaque t)+       if opaque then return Nothing else Just <$> getStructure t+  flip fix Set.empty $ \continue done -> do+    t <- takeTypeToDefine+    flip (maybe (return [])) t $ \t -> do+      if t `Set.member` done+        then+          continue done+        else+          return (:)+            `ap` (return A.TypeDefinition `ap` getTypeName t `ap` getStructDefinition t)+            `ap` (continue $ Set.insert t done)++isArrayType :: Ptr FFI.Type -> IO Bool+isArrayType t = do+  k <- liftIO $ FFI.getTypeKind t+  return $ k == FFI.typeKindArray++instance Monad m => EncodeM m A.AddrSpace FFI.AddrSpace where+  encodeM (A.AddrSpace a) = return FFI.AddrSpace `ap` encodeM a++instance Monad m => DecodeM m A.AddrSpace FFI.AddrSpace where+  decodeM (FFI.AddrSpace a) = return A.AddrSpace `ap` decodeM a++instance EncodeM EncodeAST A.Type (Ptr FFI.Type) where+  encodeM f = scopeAnyCont $ do+    Context context <- gets encodeStateContext+    case f of+      A.IntegerType bits -> do+        bits <- encodeM bits+        liftIO $ FFI.intTypeInContext context bits+      A.FunctionType returnTypeAST argTypeASTs isVarArg -> do+        returnType <- encodeM returnTypeAST+        argTypes <- encodeM argTypeASTs+        isVarArg <- encodeM isVarArg+        liftIO $ FFI.functionType returnType argTypes isVarArg+      A.PointerType elementType addressSpace -> do+        e <- encodeM elementType+        a <- encodeM addressSpace+        liftIO $ FFI.pointerType e a+      A.VoidType -> liftIO $ FFI.voidTypeInContext context+      A.FloatingPointType 16 A.IEEE -> liftIO $ FFI.halfTypeInContext context+      A.FloatingPointType 32 A.IEEE -> liftIO $ FFI.floatTypeInContext context+      A.FloatingPointType 64 A.IEEE -> liftIO $ FFI.doubleTypeInContext context+      A.FloatingPointType 80 A.DoubleExtended -> liftIO $ FFI.x86FP80TypeInContext context+      A.FloatingPointType 128 A.IEEE -> liftIO $ FFI.fP128TypeInContext context+      A.FloatingPointType 128 A.PairOfFloats -> liftIO $ FFI.ppcFP128TypeInContext context+      A.FloatingPointType _ _ -> throwError $ "unsupported floating point type: " ++ show f+      A.VectorType sz e -> do+        e <- encodeM e+        sz <- encodeM sz+        liftIO $ FFI.vectorType e sz+      A.ArrayType sz e -> do+        e <- encodeM e+        sz <- encodeM sz+        liftIO $ FFI.arrayType e sz+      A.StructureType packed ets -> do+        ets <- encodeM ets+        packed <- encodeM packed+        liftIO $ FFI.structTypeInContext context ets packed+      A.NamedTypeReference n -> lookupNamedType n+      A.MetadataType -> liftIO $ FFI.metadataTypeInContext context+      A.TokenType -> liftIO $ FFI.tokenTypeInContext context++instance DecodeM DecodeAST A.Type (Ptr FFI.Type) where+  decodeM t = scopeAnyCont $ do+    k <- liftIO $ FFI.getTypeKind t+    case k of+      [typeKindP|Void|] -> return A.VoidType+      [typeKindP|Integer|] -> A.IntegerType <$> (decodeM =<< liftIO (FFI.getIntTypeWidth t))+      [typeKindP|Function|] ->+          return A.FunctionType+               `ap` (decodeM =<< liftIO (FFI.getReturnType t))+               `ap` (do+                      n <- liftIO (FFI.countParamTypes t)+                      ts <- allocaArray n+                      liftIO $ FFI.getParamTypes t ts+                      decodeM (n, ts)+                   )+               `ap` (decodeM =<< liftIO (FFI.isFunctionVarArg t))+      [typeKindP|Pointer|] ->+          return A.PointerType+             `ap` (decodeM =<< liftIO (FFI.getElementType t))+             `ap` (decodeM =<< liftIO (FFI.getPointerAddressSpace t))+      [typeKindP|Half|] -> return $ A.FloatingPointType 16 A.IEEE+      [typeKindP|Float|] -> return $ A.FloatingPointType 32 A.IEEE+      [typeKindP|Double|] -> return $ A.FloatingPointType 64 A.IEEE+      [typeKindP|FP128|] -> return $ A.FloatingPointType 128 A.IEEE+      [typeKindP|X86_FP80|] -> return $ A.FloatingPointType 80 A.DoubleExtended+      [typeKindP|PPC_FP128|] -> return $ A.FloatingPointType 128 A.PairOfFloats+      [typeKindP|Vector|] ->+        return A.VectorType+         `ap` (decodeM =<< liftIO (FFI.getVectorSize t))+         `ap` (decodeM =<< liftIO (FFI.getElementType t))+      [typeKindP|Struct|] -> do+        let ifM c a b = c >>= \x -> if x then a else b+        ifM (decodeM =<< liftIO (FFI.structIsLiteral t))+            (getStructure t)+            (saveNamedType t >> return A.NamedTypeReference `ap` getTypeName t)+      [typeKindP|Metadata|] -> return A.MetadataType+      [typeKindP|Array|] ->+        return A.ArrayType+         `ap` (decodeM =<< liftIO (FFI.getArrayLength t))+         `ap` (decodeM =<< liftIO (FFI.getElementType t))+      [typeKindP|Token|] -> return A.TokenType+      _ -> error $ "unhandled type kind " ++ show k++createNamedType :: A.Name -> EncodeAST (Ptr FFI.Type)+createNamedType n = do+  Context c <- gets encodeStateContext+  n <- case n of { A.Name n -> encodeM n; _ -> return nullPtr }+  liftIO $ FFI.structCreateNamed c n+++setNamedType :: Ptr FFI.Type -> A.Type -> EncodeAST ()+setNamedType t (A.StructureType packed ets) = do+  ets <- encodeM ets+  packed <- encodeM packed+  liftIO $ FFI.structSetBody t ets packed+++
+ src/LLVM/Internal/Value.hs view
@@ -0,0 +1,24 @@+{-# LANGUAGE+  MultiParamTypeClasses+  #-}+module LLVM.Internal.Value where++import LLVM.Prelude++import Control.Monad.State++import Foreign.Ptr++import qualified LLVM.Internal.FFI.PtrHierarchy as FFI+import qualified LLVM.Internal.FFI.Value as FFI++import LLVM.Internal.Coding+import LLVM.Internal.DecodeAST+import LLVM.Internal.Type () +import LLVM.Internal.Constant () ++import qualified LLVM.AST.Type as A++typeOf :: FFI.DescendentOf FFI.Value v => Ptr v -> DecodeAST A.Type+typeOf = decodeM <=< liftIO . FFI.typeOf . FFI.upCast+
+ src/LLVM/Module.hs view
@@ -0,0 +1,27 @@+-- | A 'Module' holds a C++ LLVM IR module. 'Module's may be converted to or from strings or Haskell ASTs, or+-- added to an 'LLVM.ExecutionEngine.ExecutionEngine' and so JIT compiled to get function pointers.+module LLVM.Module (+    Module,+    File(..),++    withModuleFromAST,+    moduleAST,++    withModuleFromLLVMAssembly,+    moduleLLVMAssembly,+    writeLLVMAssemblyToFile,++    withModuleFromBitcode,+    moduleBitcode,+    writeBitcodeToFile,++    moduleTargetAssembly,+    writeTargetAssemblyToFile,++    moduleObject,+    writeObjectToFile,++    linkModules+  ) where++import LLVM.Internal.Module
+ src/LLVM/OrcJIT.hs view
@@ -0,0 +1,11 @@+module LLVM.OrcJIT (+    JITSymbol(..),+    JITSymbolFlags(..),+    MangledSymbol,+    ObjectLinkingLayer,+    SymbolResolver(..),+    SymbolResolverFn,+    withObjectLinkingLayer+  ) where++import LLVM.Internal.OrcJIT
+ src/LLVM/OrcJIT/CompileOnDemandLayer.hs view
@@ -0,0 +1,14 @@+module LLVM.OrcJIT.CompileOnDemandLayer (+    PartitioningFn,+    JITCompileCallbackManager,+    IndirectStubsManagerBuilder,+    CompileOnDemandLayer,+    withIndirectStubsManagerBuilder,+    withJITCompileCallbackManager,+    withCompileOnDemandLayer,+    mangleSymbol,+    findSymbol,+    withModuleSet+  ) where++import LLVM.Internal.OrcJIT.CompileOnDemandLayer
+ src/LLVM/OrcJIT/IRCompileLayer.hs view
@@ -0,0 +1,10 @@+module LLVM.OrcJIT.IRCompileLayer (+    IRCompileLayer,+    ModuleSet,+    findSymbol,+    mangleSymbol,+    withIRCompileLayer,+    withModuleSet+  ) where++import           LLVM.Internal.OrcJIT.IRCompileLayer
+ src/LLVM/PassManager.hs view
@@ -0,0 +1,14 @@+-- | A 'PassManager' holds collection of passes, to be run on 'Module's.+-- Build one with 'withPassManager':+-- +--  * using 'CuratedPassSetSpec' if you want optimization but not to play with your compiler+--+--  * using 'PassSetSpec' if you do want to play with your compiler+module LLVM.PassManager (+  PassManager,+  PassSetSpec(..), defaultPassSetSpec, defaultCuratedPassSetSpec,+  withPassManager,+  runPassManager+  ) where++import LLVM.Internal.PassManager
+ src/LLVM/Relocation.hs view
@@ -0,0 +1,12 @@+-- | Relocations, used in specifying TargetMachine+module LLVM.Relocation where++import LLVM.Prelude++-- | <http://llvm.org/doxygen/namespacellvm_1_1Reloc.html>+data Model +    = Default+    | Static+    | PIC+    | DynamicNoPIC+    deriving (Eq, Read, Show, Typeable, Data)
+ src/LLVM/Target.hs view
@@ -0,0 +1,22 @@+-- | A 'Target' describes that for which code may be intended. Targets are used both during actual+-- | lowering of LLVM IR to machine code and by some optimization passes which use the target to+-- | judge costs.+module LLVM.Target (+   lookupTarget,+   TargetOptions,+   Target, TargetMachine, TargetLowering,+   CPUFeature(..),+   withTargetOptions, peekTargetOptions, pokeTargetOptions,+   withTargetMachine, withHostTargetMachine,+   getTargetLowering,+   getTargetMachineTriple, getDefaultTargetTriple, getProcessTargetTriple, getHostCPUName, getHostCPUFeatures,+   getTargetMachineDataLayout, initializeNativeTarget, initializeAllTargets,+   TargetLibraryInfo,+   getLibraryFunction,+   getLibraryFunctionName,+   setLibraryFunctionAvailableWithName,+   withTargetLibraryInfo+ ) where++import LLVM.Internal.Target+
+ src/LLVM/Target/LibraryFunction.hs view
@@ -0,0 +1,7 @@+-- | A 'LibraryFunction' identifies a function of which LLVM has particular knowledge.+module LLVM.Target.LibraryFunction (+  LibraryFunction(..)+ ) where+++import LLVM.Internal.LibraryFunction
+ src/LLVM/Target/Options.hs view
@@ -0,0 +1,41 @@+-- | <http://llvm.org/doxygen/classllvm_1_1TargetOptions.html>+module LLVM.Target.Options where++import LLVM.Prelude++-- | <http://llvm.org/doxygen/namespacellvm_1_1FloatABI.html#aea077c52d84934aabf9445cef9eab2e2>+data FloatABI+  = FloatABIDefault+  | FloatABISoft+  | FloatABIHard+  deriving (Eq, Ord, Read, Show, Enum, Bounded, Typeable, Data)++-- | <http://llvm.org/doxygen/namespacellvm_1_1FPOpFusion.html#a9c71bae9f02af273833fde586d529fc5>+data FloatingPointOperationFusionMode+  = FloatingPointOperationFusionFast+  | FloatingPointOperationFusionStandard+  | FloatingPointOperationFusionStrict+  deriving (Eq, Ord, Read, Show, Enum, Bounded, Typeable, Data)++-- | The options of a 'LLVM.Target.TargetOptions'+-- <http://llvm.org/doxygen/classllvm_1_1TargetOptions.html>+data Options = Options {+  printMachineCode :: Bool,+  lessPreciseFloatingPointMultiplyAddOption :: Bool,+  unsafeFloatingPointMath :: Bool,+  noInfinitiesFloatingPointMath :: Bool,+  noNaNsFloatingPointMath :: Bool,+  honorSignDependentRoundingFloatingPointMathOption :: Bool,+  noZerosInBSS :: Bool,+  guaranteedTailCallOptimization :: Bool,+  enableFastInstructionSelection :: Bool,+  useInitArray :: Bool,+  disableIntegratedAssembler :: Bool,+  compressDebugSections :: Bool,+  trapUnreachable :: Bool,+  stackAlignmentOverride :: Word32,+  floatABIType :: FloatABI,+  allowFloatingPointOperationFusion :: FloatingPointOperationFusionMode+  }+  deriving (Eq, Ord, Read, Show)+
+ src/LLVM/Threading.hs view
@@ -0,0 +1,24 @@+-- | functionality necessary when running LLVM in multiple threads at the same time.+module LLVM.Threading (+  setMultithreaded,+  isMultithreaded+  ) where++import LLVM.Prelude++import LLVM.Internal.Threading++{-# DEPRECATED setMultithreaded "LLVM no longer features runtime control of multithreading support" #-}+-- | This function used set the multithreading mode of LLVM, but that feature no longer exists. Threading is+-- controlled only at runtime with the configure flag --enable-threads (default is YES). This function will+-- now check that the the compiled-in multithreading support (returned by 'isMultithreaded') is+-- sufficient to support the requested access, and fail if not, so as to prevent uncontrolled use of a+-- version of LLVM compiled to be capable only of singled threaded use by haskell code requesting+-- multithreading support.+setMultithreaded :: Bool -> IO ()+setMultithreaded desired = do+  actual <- isMultithreaded+  when (desired && not actual) $+     fail $ "Multithreading support requested but not available. " ++ +            "Please use an LLVM built with threading enabled"+  return ()
+ src/LLVM/Transforms.hs view
@@ -0,0 +1,197 @@+-- | This module provides an enumeration of the various transformation (e.g. optimization) passes+-- provided by LLVM. They can be used to create a 'LLVM.PassManager.PassManager' to, in turn,+-- run the passes on 'LLVM.Module.Module's. If you don't know what passes you want, consider+-- instead using 'LLVM.PassManager.CuratedPassSetSpec'.+module LLVM.Transforms where++import LLVM.Prelude++-- | <http://llvm.org/docs/Passes.html#transform-passes>+-- A few passes can make use of information in a 'LLVM.Target.TargetMachine' if one+-- is provided to 'LLVM.PassManager.createPassManager'.+-- <http://llvm.org/doxygen/classllvm_1_1Pass.html>+data Pass+  -- here begin the Scalar passes+  = AggressiveDeadCodeElimination+  | BreakCriticalEdges+  -- | can use a 'LLVM.Target.TargetMachine'+  | CodeGenPrepare+  | ConstantPropagation+  | CorrelatedValuePropagation+  | DeadCodeElimination+  | DeadInstructionElimination+  | DeadStoreElimination+  | DemoteRegisterToMemory+  | EarlyCommonSubexpressionElimination+  | GlobalValueNumbering { noLoads :: Bool }+  | InductionVariableSimplify+  | InstructionCombining+  | JumpThreading+  | LoopClosedSingleStaticAssignment+  | LoopInvariantCodeMotion+  | LoopDeletion+  | LoopIdiom+  | LoopInstructionSimplify+  | LoopRotate+  | LoopStrengthReduce+  | LoopUnroll { loopUnrollThreshold :: Maybe Word, count :: Maybe Word, allowPartial :: Maybe Bool }+  | LoopUnswitch { optimizeForSize :: Bool }+  | LowerAtomic+  | LowerInvoke+  | LowerSwitch+  | LowerExpectIntrinsic+  | MemcpyOptimization+  | PromoteMemoryToRegister+  | Reassociate+  | ScalarReplacementOfAggregates { requiresDominatorTree :: Bool }+  | OldScalarReplacementOfAggregates { +      oldScalarReplacementOfAggregatesThreshold :: Maybe Word, +      useDominatorTree :: Bool, +      structMemberThreshold :: Maybe Word,+      arrayElementThreshold :: Maybe Word,+      scalarLoadThreshold :: Maybe Word+    }+  | SparseConditionalConstantPropagation+  | SimplifyLibCalls+  | SimplifyControlFlowGraph+  | Sinking+  | TailCallElimination++  -- here begin the Interprocedural passes+  | AlwaysInline { insertLifetime :: Bool }+  | ArgumentPromotion+  | ConstantMerge+  | FunctionAttributes+  | FunctionInlining { +      functionInliningThreshold :: Word+    }+  | GlobalDeadCodeElimination+  | InternalizeFunctions { exportList :: [String] }+  | InterproceduralConstantPropagation+  | InterproceduralSparseConditionalConstantPropagation+  | MergeFunctions+  | PartialInlining+  | PruneExceptionHandling+  | StripDeadDebugInfo+  | StripDebugDeclare+  | StripNonDebugSymbols+  | StripSymbols { onlyDebugInfo :: Bool }++  -- here begin the vectorization passes+  | BasicBlockVectorize { +      vectorBits :: Word,+      vectorizeBools :: Bool,+      vectorizeInts :: Bool,+      vectorizeFloats :: Bool,+      vectorizePointers :: Bool,+      vectorizeCasts :: Bool,+      vectorizeMath :: Bool,+      vectorizeFusedMultiplyAdd :: Bool,+      vectorizeSelect :: Bool,+      vectorizeCmp :: Bool,+      vectorizeGetElementPtr :: Bool,+      vectorizeMemoryOperations :: Bool,+      alignedOnly :: Bool,+      requiredChainDepth :: Word,+      searchLimit :: Word,+      maxCandidatePairsForCycleCheck :: Word,+      splatBreaksChain :: Bool,+      maxInstructions :: Word,+      maxIterations :: Word,+      powerOfTwoLengthsOnly :: Bool,+      noMemoryOperationBoost :: Bool,+      fastDependencyAnalysis :: Bool+    }+  | LoopVectorize {+      noUnrolling :: Bool,+      alwaysVectorize :: Bool+    }+  | SuperwordLevelParallelismVectorize++  -- here begin the instrumentation passes+  | GCOVProfiler {+      emitNotes :: Bool,+      emitData :: Bool,+      version :: GCOVVersion, +      useCfgChecksum :: Bool,+      noRedZone :: Bool,+      functionNamesInData :: Bool+    }+  | AddressSanitizer+  | AddressSanitizerModule+  | MemorySanitizer {+      trackOrigins :: Bool+    }+  | ThreadSanitizer+  | BoundsChecking+  deriving (Eq, Ord, Read, Show, Typeable, Data)++-- | Defaults for the 'LoopVectorize' pass+defaultLoopVectorize :: Pass+defaultLoopVectorize = LoopVectorize {+    noUnrolling = False,+    alwaysVectorize = True+  }++-- | Defaults for the 'BasicBlockVectorize' pass - copied from the C++ code to keep these defaults+-- constant. (The C++ defaults are modifiable through global objects used for command-line processing,+-- in a design apparently oblivious to uses of LLVM besides the standard command-line tools).+defaultVectorizeBasicBlocks :: Pass+defaultVectorizeBasicBlocks = BasicBlockVectorize {+    vectorBits = 128,+    vectorizeBools = True,+    vectorizeInts = True,+    vectorizeFloats = True,+    vectorizePointers = True,+    vectorizeCasts = True,+    vectorizeMath = True,+    vectorizeFusedMultiplyAdd = True,+    vectorizeSelect = True,+    vectorizeCmp = True,+    vectorizeGetElementPtr = True,+    vectorizeMemoryOperations = True,+    alignedOnly = True,++    requiredChainDepth = 6,+    searchLimit = 400,+    maxCandidatePairsForCycleCheck = 200,+    splatBreaksChain = False,+    maxInstructions = 500,+    maxIterations = 0,+    powerOfTwoLengthsOnly = False,+    noMemoryOperationBoost = False,+    fastDependencyAnalysis = False+  }++-- | See <http://gcc.gnu.org/viewcvs/gcc/trunk/gcc/gcov-io.h?view=markup>.+newtype GCOVVersion = GCOVVersion String+  deriving (Eq, Ord, Read, Show, Typeable, Data)++-- | Defaults for 'GCOVProfiler'.+defaultGCOVProfiler :: Pass+defaultGCOVProfiler = GCOVProfiler {+    emitNotes = True,+    emitData = True,+    version = GCOVVersion "402*", +    useCfgChecksum = False,+    noRedZone = False,+    functionNamesInData = True+  }++-- | Defaults for 'AddressSanitizer'.+defaultAddressSanitizer :: Pass+defaultAddressSanitizer = AddressSanitizer++-- | Defaults for 'AddressSanitizerModule'.+defaultAddressSanitizerModule :: Pass+defaultAddressSanitizerModule = AddressSanitizerModule++-- | Defaults for 'MemorySanitizer'.+defaultMemorySanitizer :: Pass+defaultMemorySanitizer = MemorySanitizer {+  trackOrigins = False+}++-- | Defaults for 'ThreadSanitizer'.+defaultThreadSanitizer :: Pass+defaultThreadSanitizer = ThreadSanitizer
+ test/LLVM/Test/Analysis.hs view
@@ -0,0 +1,113 @@+module LLVM.Test.Analysis where++import Test.Tasty+import Test.Tasty.HUnit++import LLVM.Test.Support++import Control.Monad.Trans.Except++import LLVM.Module+import LLVM.Context+import LLVM.Analysis++import LLVM.AST as A+import LLVM.AST.Type as A.T+import LLVM.AST.Name+import LLVM.AST.AddrSpace+import LLVM.AST.DataLayout+import qualified LLVM.AST.IntegerPredicate as IPred+import qualified LLVM.AST.Linkage as L+import qualified LLVM.AST.Visibility as V+import qualified LLVM.AST.CallingConvention as CC+import qualified LLVM.AST.Attribute as A+import qualified LLVM.AST.Global as G+import qualified LLVM.AST.Constant as C++import qualified LLVM.Relocation as R+import qualified LLVM.CodeModel as CM+import qualified LLVM.CodeGenOpt as CGO++tests = testGroup "Analysis" [+  testGroup "Verifier" [+{-+    -- this test will cause an assertion if LLVM is compiled with assertions on.+    testCase "Module" $ do+      let ast = Module "<string>" Nothing Nothing [+            GlobalDefinition $ Function L.External V.Default CC.C [] A.T.void (Name "foo") ([+                Parameter i32 (Name "x") []+               ],False)+             [] +             Nothing 0 Nothing         +             [+              BasicBlock (UnName 0) [+                UnName 1 := Call {+                  isTailCall = False,+                  callingConvention = CC.C,+                  returnAttributes = [],+                  function = Right (ConstantOperand (C.GlobalReference (A.T.FunctionType A.T.void [A.T.i32] False) (Name "foo"))),+                  arguments = [+                   (ConstantOperand (C.Int 8 1), [])+                  ],+                  functionAttributes = [],+                  metadata = []+                 }+              ] (+                Do $ Ret Nothing []+              )+             ]+            ]+      Left s <- withContext $ \context -> withModuleFromAST' context ast $ runExceptT . verify+      s @?= "Call parameter type does not match function signature!\n\+            \i8 1\n\+            \ i32  call void @foo(i8 1)\n\+            \Broken module found, compilation terminated.\n\+            \Broken module found, compilation terminated.\n",+-}++    testGroup "regression" [+      testCase "load synchronization" $ do+       let str = "; ModuleID = '<string>'\n\+                 \source_filename = \"<string>\"\n\+                 \\n\+                 \define double @my_function2(double* %input_0) {\n\+                 \foo:\n\+                 \  %tmp_input_w0 = getelementptr inbounds double, double* %input_0, i64 0\n\+                 \  %0 = load double, double* %tmp_input_w0, align 8\n\+                 \  ret double %0\n\+                 \}\n"+           ast = +             Module "<string>" "<string>" Nothing Nothing [+               GlobalDefinition $ functionDefaults {+                 G.returnType = double,+                 G.name = Name "my_function2",+                 G.parameters = ([+                   Parameter (ptr double) (Name "input_0") []+                  ],False),+                 G.basicBlocks = [+                   BasicBlock (Name "foo") [ +                    Name "tmp_input_w0" := GetElementPtr {+                      inBounds = True,+                      address = LocalReference (ptr double) (Name "input_0"),+                      indices = [ConstantOperand (C.Int 64 0)],+                      metadata = []+                    },+                    UnName 0 := Load {+                      volatile = False,+                      address = LocalReference (ptr double) (Name "tmp_input_w0"),+                      maybeAtomicity = Nothing,+                      alignment = 8,+                      metadata = []+                    }+                   ] (+                     Do $ Ret (Just (LocalReference double (UnName 0))) []+                   )+                  ]+                }+              ]+       strCheck ast str+       s <- withContext $ \context -> withModuleFromAST' context ast $ runExceptT . verify+       s @?= Right ()+     ]+   ]+ ]
+ test/LLVM/Test/CallingConvention.hs view
@@ -0,0 +1,57 @@+module LLVM.Test.CallingConvention where++import Test.Tasty+import Test.Tasty.HUnit++import LLVM.Test.Support++import Data.Maybe+import qualified Data.Set as Set+import qualified Data.Map as Map++import LLVM.Context+import LLVM.Module+import LLVM.AST+import LLVM.AST.Type as T+import qualified LLVM.AST.CallingConvention as CC+import qualified LLVM.AST.Global as G++tests = testGroup "CallingConvention" [+  testCase name $ strCheck (defaultModule {+    moduleDefinitions = [+     GlobalDefinition $ functionDefaults {+       G.returnType = i32,+       G.name = Name "foo",+       G.callingConvention = cc+     }+    ]+   }) ("; ModuleID = '<string>'\n\+       \source_filename = \"<string>\"\n\+       \\n\+       \declare" ++ (if name == "" then "" else (" " ++ name)) ++ " i32 @foo()\n")+   | (name, cc) <- [+   ("", CC.C),+   ("fastcc", CC.Fast),+   ("coldcc", CC.Cold),+   ("ghccc", CC.GHC),+   ("cc11", CC.HiPE),+   ("webkit_jscc", CC.WebKit_JS),+   ("anyregcc", CC.AnyReg),+   ("preserve_mostcc", CC.PreserveMost),+   ("preserve_allcc", CC.PreserveAll),+   ("x86_stdcallcc", CC.X86_StdCall),+   ("x86_fastcallcc", CC.X86_FastCall),+   ("arm_apcscc", CC.ARM_APCS),+   ("arm_aapcscc", CC.ARM_AAPCS),+   ("arm_aapcs_vfpcc", CC.ARM_AAPCS_VFP),+   ("msp430_intrcc", CC.MSP430_INTR),+   ("x86_thiscallcc", CC.X86_ThisCall),+   ("ptx_kernel", CC.PTX_Kernel),+   ("ptx_device", CC.PTX_Device),+   ("spir_func", CC.SPIR_FUNC),+   ("spir_kernel", CC.SPIR_KERNEL),+   ("intel_ocl_bicc", CC.Intel_OCL_BI),+   ("x86_64_sysvcc", CC.X86_64_SysV),+   ("x86_64_win64cc", CC.X86_64_Win64)+  ]+ ]
+ test/LLVM/Test/Constants.hs view
@@ -0,0 +1,184 @@+module LLVM.Test.Constants where++import Test.Tasty+import Test.Tasty.HUnit++import LLVM.Test.Support++import Control.Monad+import Data.Functor+import Data.Maybe+import Foreign.Ptr+import Data.Word++import LLVM.Context+import LLVM.Module+import LLVM.Diagnostic+import LLVM.AST+import LLVM.AST.Type+import LLVM.AST.Name+import LLVM.AST.AddrSpace+import qualified LLVM.AST.Linkage as L+import qualified LLVM.AST.Visibility as V+import qualified LLVM.AST.CallingConvention as CC+import qualified LLVM.AST.Attribute as A+import qualified LLVM.AST.Global as G+import qualified LLVM.AST.Constant as C+import qualified LLVM.AST.Float as F+import qualified LLVM.AST.IntegerPredicate as IPred++tests = testGroup "Constants" [+  testCase name $ strCheck mAST mStr+  | (name, type', value, str) <- [+    (+      "integer",+      i32,+      C.Int 32 1,+      "global i32 1"+    ), (+      "wide integer",+      IntegerType 65,+      C.Int 65 1,+      "global i65 1"+    ), (+      "big wide integer",+      IntegerType 66,+      C.Int 66 20000000000000000000,+      "global i66 20000000000000000000"+    ), (+      "negative wide integer",+      IntegerType 65,+      C.Int 65 36893488147419103231,+      "global i65 -1"+    ), (+      "half",+      half,+      C.Float (F.Half 0x1234),+      "global half 0xH1234"+    ), (+      "float",+      float,+      C.Float (F.Single 1),+      "global float 1.000000e+00"+    ), (+      "double",+      double,+      C.Float (F.Double 1),+      "global double 1.000000e+00"+    ), (+      "quad",+      fp128,+      C.Float (F.Quadruple 0x0007000600050004 0x0003000200010000),+      "global fp128 0xL00030002000100000007000600050004" -- yes, this order is weird+    ), (+      "quad 1.0",+      fp128,+      C.Float (F.Quadruple 0x3fff000000000000 0x0000000000000000),+      "global fp128 0xL00000000000000003FFF000000000000" -- yes, this order is weird+    ), (+      "x86_fp80",+      x86_fp80,+      C.Float (F.X86_FP80 0x0004 0x0003000200010000),+      "global x86_fp80 0xK00040003000200010000"+{- don't know how to test this - LLVM's handling of this weird type is even weirder+    ), (+      "ppc_fp128",+      ppc_fp128,+      C.Float (F.PPC_FP128 0x0007000600050004 0x0003000200010000),+      "global ppc_fp128 0xM????????????????"+-}+    ), (+      "struct",+      StructureType False (replicate 2 i32),+      C.Struct Nothing False (replicate 2 (C.Int 32 1)),+      "global { i32, i32 } { i32 1, i32 1 }"+    ), (+      "dataarray",+      ArrayType 3 i32,+      C.Array i32 [C.Int 32 i | i <- [1,2,1]],+      "global [3 x i32] [i32 1, i32 2, i32 1]"+    ), (+      "array",+      ArrayType 3 (StructureType False [i32]),+      C.Array (StructureType False [i32]) [C.Struct Nothing False [C.Int 32 i] | i <- [1,2,1]],+      "global [3 x { i32 }] [{ i32 } { i32 1 }, { i32 } { i32 2 }, { i32 } { i32 1 }]"+    ), (+      "datavector",+      VectorType 3 i32,+      C.Vector [C.Int 32 i | i <- [1,2,1]],+      "global <3 x i32> <i32 1, i32 2, i32 1>"+    ), (+      "undef",+      i32,+      C.Undef i32,+      "global i32 undef"+    ), (+      "binop/cast",+      i64,+      C.Add False False (C.PtrToInt (C.GlobalReference (ptr i32) (UnName 1)) i64) (C.Int 64 2),+      "global i64 add (i64 ptrtoint (i32* @1 to i64), i64 2)"+    ), (+      "binop/cast nsw",+      i64,+      C.Add True False (C.PtrToInt (C.GlobalReference (ptr i32) (UnName 1)) i64) (C.Int 64 2),+      "global i64 add nsw (i64 ptrtoint (i32* @1 to i64), i64 2)"+    ), (+      "icmp",+      i1,+      C.ICmp IPred.SGE (C.GlobalReference (ptr i32) (UnName 1)) (C.GlobalReference (ptr i32) (UnName 2)),+      "global i1 icmp sge (i32* @1, i32* @2)"+    ), (+      "getelementptr",+      ptr i32,+      C.GetElementPtr True (C.GlobalReference (ptr i32) (UnName 1)) [C.Int 64 27],+      "global i32* getelementptr inbounds (i32, i32* @1, i64 27)"+    ), (+      "selectvalue",+      i32,+      C.Select (C.PtrToInt (C.GlobalReference (ptr i32) (UnName 1)) i1) +         (C.Int 32 1)+         (C.Int 32 2),+      "global i32 select (i1 ptrtoint (i32* @1 to i1), i32 1, i32 2)"+    ), (+      "extractelement",+      i32,+      C.ExtractElement+         (C.BitCast+             (C.PtrToInt (C.GlobalReference (ptr i32) (UnName 1)) i64)+             (VectorType 2 i32))+         (C.Int 32 1),+      "global i32 extractelement (<2 x i32> bitcast (i64 ptrtoint (i32* @1 to i64) to <2 x i32>), i32 1)"+    ), (+     "addrspacecast",+     (PointerType i32 (AddrSpace 1)),+     C.AddrSpaceCast (C.GlobalReference (ptr i32) (UnName 1)) (PointerType i32 (AddrSpace 1)),+     "global i32 addrspace(1)* addrspacecast (i32* @1 to i32 addrspace(1)*)"+{-+    ), (+--  This test made llvm abort as of llvm-3.2.  Now, as a new feature in llvm-3.4, it makes it report a fatal error!+      "extractvalue",+      i8,+      C.ExtractValue+        (C.Select (C.PtrToInt (C.GlobalReference (p i32) (UnName 1)) i1) +         (C.Array i8 [C.Int 8 0])+         (C.Array i8 [C.Int 8 1]))+        [0],+      "global i8 extractvalue ([1 x i8] select (i1 ptrtoint (i32* @1 to i1), [1 x i8] [ i8 1 ], [1 x i8] [ i8 2 ]), 0)"+-}+    )+   ],+   let mAST = Module "<string>" "<string>" Nothing Nothing [+             GlobalDefinition $ globalVariableDefaults {+               G.name = UnName 0, G.type' = type', G.initializer = Just value +             },+             GlobalDefinition $ globalVariableDefaults {+               G.name = UnName 1, G.type' = i32, G.initializer = Nothing +             },+             GlobalDefinition $ globalVariableDefaults {+               G.name = UnName 2, G.type' = i32, G.initializer = Nothing +             }+           ]+       mStr = "; ModuleID = '<string>'\nsource_filename = \"<string>\"\n\n@0 = " ++ str ++ "\n\+              \@1 = external global i32\n\+              \@2 = external global i32\n"+ ]
+ test/LLVM/Test/DataLayout.hs view
@@ -0,0 +1,86 @@+module LLVM.Test.DataLayout where++import Test.Tasty+import Test.Tasty.HUnit++import LLVM.Test.Support++import Data.Maybe+import qualified Data.Set as Set+import qualified Data.Map as Map++import LLVM.Context+import LLVM.Module+import LLVM.AST+import LLVM.AST.DataLayout+import LLVM.AST.AddrSpace+import qualified LLVM.AST.Global as G++m s = "; ModuleID = '<string>'\nsource_filename = \"<string>\"\n" ++ s+t s = "target datalayout = \"" ++ s ++ "\"\n"+ddl = defaultDataLayout BigEndian++tests = testGroup "DataLayout" [+  testCase name $ strCheckC (Module "<string>" "<string>" mdl Nothing []) (m sdl) (m sdlc)+  | (name, mdl, sdl, sdlc) <- [+   ("none", Nothing, "", "")+  ] ++ [+   (name, Just mdl, t sdl, t (fromMaybe sdl msdlc))+   | (name, mdl, sdl, msdlc) <- [+    ("little-endian", defaultDataLayout LittleEndian, "e", Nothing),+    ("big-endian", defaultDataLayout BigEndian, "E", Nothing),+    ("native", ddl { nativeSizes = Just (Set.fromList [8,32]) }, "E-n8:32", Nothing),+    (+     "no pref",+     ddl {+       pointerLayouts = +         Map.singleton+         (AddrSpace 0) +         (+          8,+          AlignmentInfo {+            abiAlignment = 64,+            preferredAlignment = Nothing+          }+         )+     },+     "E-p:8:64",+     Nothing+    ), (+     "no pref",+     ddl {+       pointerLayouts = +         Map.insert (AddrSpace 1) (8, AlignmentInfo 32 (Just 64)) (pointerLayouts ddl)+     },+     "E-p1:8:32:64",+     Nothing+    ), (+     "big",+     ddl {+       endianness = LittleEndian,+       mangling = Just ELFMangling,+       stackAlignment = Just 128,+       pointerLayouts = Map.fromList [+         (AddrSpace 0, (8, AlignmentInfo {abiAlignment = 8, preferredAlignment = Just 16}))+        ],+       typeLayouts = Map.fromList [+         ((IntegerAlign, 1), AlignmentInfo {abiAlignment = 8, preferredAlignment = Just 256}),+         ((IntegerAlign, 8), AlignmentInfo {abiAlignment = 8, preferredAlignment = Just 256}),+         ((IntegerAlign, 16), AlignmentInfo {abiAlignment = 16, preferredAlignment = Just 256}),+         ((IntegerAlign, 32), AlignmentInfo {abiAlignment = 32, preferredAlignment = Just 256}),+         ((IntegerAlign, 64), AlignmentInfo {abiAlignment = 64, preferredAlignment = Just 256}),+         ((VectorAlign, 64), AlignmentInfo {abiAlignment = 64, preferredAlignment = Just 256}),+         ((VectorAlign, 128), AlignmentInfo {abiAlignment = 128, preferredAlignment = Just 256}),+         ((FloatAlign, 32), AlignmentInfo {abiAlignment = 32, preferredAlignment = Just 256}),+         ((FloatAlign, 64), AlignmentInfo {abiAlignment = 64, preferredAlignment = Just 256}),+         ((FloatAlign, 80), AlignmentInfo {abiAlignment = 128, preferredAlignment = Just 256})+        ] `Map.union` typeLayouts ddl, +       aggregateLayout = AlignmentInfo {abiAlignment = 0, preferredAlignment = Just 256},+       nativeSizes = Just (Set.fromList [8,16,32,64])+     },+     "e-m:e-p:8:8:16-i1:8:256-i8:8:256-i16:16:256-i32:32:256-i64:64:256-v64:64:256-v128:128:256-f32:32:256-f64:64:256-f80:128:256-a:0:256-n8:16:32:64-S128",+     Nothing+    )+   ]+  ]+ ]
+ test/LLVM/Test/ExecutionEngine.hs view
@@ -0,0 +1,59 @@+{-# LANGUAGE+  ForeignFunctionInterface+  #-}+module LLVM.Test.ExecutionEngine where++import Test.Tasty+import Test.Tasty.HUnit++import LLVM.Test.Support++import Control.Monad+import Data.Functor+import Data.Maybe++import Foreign.Ptr+import Data.Word++import LLVM.Context+import LLVM.Module+import LLVM.ExecutionEngine+import LLVM.AST+import LLVM.AST.Type+import LLVM.AST.Name+import LLVM.AST.AddrSpace+import qualified LLVM.AST.IntegerPredicate as IPred++import qualified LLVM.AST.Linkage as L+import qualified LLVM.AST.Visibility as V+import qualified LLVM.AST.CallingConvention as CC+import qualified LLVM.AST.Attribute as A+import qualified LLVM.AST.Global as G+import qualified LLVM.AST.Constant as C++foreign import ccall "dynamic" mkIO32Stub :: FunPtr (Word32 -> IO Word32) -> (Word32 -> IO Word32)++testJIT :: ExecutionEngine e (FunPtr ()) => (Context -> (e -> IO ()) -> IO ()) -> Assertion+testJIT withEE = withContext $ \context -> withEE context $ \executionEngine -> do+  let mAST = Module "runSomethingModule" "runSomethingModule" Nothing Nothing [+              GlobalDefinition $ functionDefaults {+                G.returnType = i32,+                G.name = Name "_foo",+                G.parameters = ([Parameter i32 (Name "bar") []],False),+                G.basicBlocks = [+                  BasicBlock (UnName 0) [] (+                    Do $ Ret (Just (ConstantOperand (C.Int 32 42))) []+                  )+                ]+               }+              ]++  s <- withModuleFromAST' context mAST $ \m -> do+        withModuleInEngine executionEngine m $ \em -> do+          Just p <- getFunction em (Name "_foo")+          (mkIO32Stub ((castFunPtr p) :: FunPtr (Word32 -> IO Word32))) 7+  s @?= 42++tests = testGroup "ExecutionEngine" [+  testCase "run something with MCJIT" $ testJIT (\c -> withMCJIT c Nothing Nothing Nothing Nothing)+ ]
+ test/LLVM/Test/Global.hs view
@@ -0,0 +1,42 @@+module LLVM.Test.Global where++import Test.Tasty+import Test.Tasty.HUnit++import LLVM.Test.Support++import LLVM.Context+import LLVM.Module+import LLVM.AST+import LLVM.AST.Type as A.T+import qualified LLVM.AST.Global as G++tests = testGroup "Global" [+  testGroup "Alignment" [+    testCase name $ withContext $ \context -> do+      let ast = Module "<string>" "<string>" Nothing Nothing [ GlobalDefinition g ]+      ast' <- withModuleFromAST' context ast moduleAST+      ast' @?= ast+    | a <- [0,1],+      s <- [Nothing, Just "foo"],+      g <- [+       globalVariableDefaults {+        G.name = UnName 0,+        G.type' = i32,+        G.alignment = a,+        G.section = s+        },+       functionDefaults {+         G.returnType = A.T.void,+         G.name = UnName 0,+         G.parameters = ([], False),+         G.alignment = a,+         G.section = s+       }+       ],+      let+          gn (G.Function {}) = "function"+          gn (G.GlobalVariable {}) = "variable"+          name = gn g ++ ", align " ++ show a ++ (maybe "" ("  section " ++ ) s)+   ]+ ]
+ test/LLVM/Test/InlineAssembly.hs view
@@ -0,0 +1,81 @@+module LLVM.Test.InlineAssembly where++import Test.Tasty+import Test.Tasty.HUnit++import LLVM.Test.Support++import LLVM.Context+import LLVM.Module++import LLVM.AST+import LLVM.AST.Type+import LLVM.AST.InlineAssembly as IA+import qualified LLVM.AST.Linkage as L+import qualified LLVM.AST.Visibility as V+import qualified LLVM.AST.CallingConvention as CC+import qualified LLVM.AST.Constant as C+import qualified LLVM.AST.Global as G++tests = testGroup "InlineAssembly" [+  testCase "expression" $ do+    let ast = Module "<string>" "<string>" Nothing Nothing [+                GlobalDefinition $ +                  functionDefaults {+                    G.returnType = i32,+                    G.name = Name "foo",+                    G.parameters = ([Parameter i32 (Name "x") []],False),+                    G.basicBlocks = [+                      BasicBlock (UnName 0) [+                        UnName 1 := Call {+                          tailCallKind = Nothing,+                          callingConvention = CC.C,+                          returnAttributes = [],+                          function = Left $ InlineAssembly {+                                       IA.type' = FunctionType i32 [i32] False,+                                       assembly = "bswap $0",+                                       constraints = "=r,r",+                                       hasSideEffects = False,+                                       alignStack = False,+                                       dialect = ATTDialect+                                     },+                          arguments = [+                            (LocalReference i32 (Name "x"), [])+                           ],+                          functionAttributes = [],+                          metadata = []+                        }+                      ] (+                        Do $ Ret (Just (LocalReference i32 (UnName 1))) []+                      )+                    ]+                }++              ]+        s = "; ModuleID = '<string>'\n\+             \source_filename = \"<string>\"\n\+             \\n\+             \define i32 @foo(i32 %x) {\n\+             \  %1 = call i32 asm \"bswap $0\", \"=r,r\"(i32 %x)\n\+             \  ret i32 %1\n\+             \}\n"+    strCheck ast s,++  testCase "module" $ do+    let ast = Module "<string>" "<string>" Nothing Nothing [+                ModuleInlineAssembly "foo",+                ModuleInlineAssembly "bar",+                GlobalDefinition $ globalVariableDefaults {+                  G.name = UnName 0,+                  G.type' = i32+                }+              ]+        s = "; ModuleID = '<string>'\n\+             \source_filename = \"<string>\"\n\+             \\n\+             \module asm \"foo\"\n\+             \module asm \"bar\"\n\+             \\n\+             \@0 = external global i32\n"+    strCheck ast s+ ]
+ test/LLVM/Test/Instructions.hs view
@@ -0,0 +1,1235 @@+module LLVM.Test.Instructions where++import Test.Tasty+import Test.Tasty.HUnit++import LLVM.Test.Support++import Control.Monad+import Data.Functor+import Data.List.NonEmpty (NonEmpty((:|)))+import Data.Maybe+import Foreign.Ptr+import Data.Word++import LLVM.Context+import LLVM.Module+import LLVM.Diagnostic+import LLVM.AST+import LLVM.AST.Type as A.T+import LLVM.AST.Name+import LLVM.AST.AddrSpace+import qualified LLVM.AST.IntegerPredicate as IPred+import qualified LLVM.AST.FloatingPointPredicate as FPPred+import qualified LLVM.AST.Linkage as L+import qualified LLVM.AST.Visibility as V+import qualified LLVM.AST.CallingConvention as CC+import qualified LLVM.AST.Attribute as A+import qualified LLVM.AST.Global as G+import qualified LLVM.AST.Constant as C+import qualified LLVM.AST.RMWOperation as RMWOp++tests = testGroup "Instructions" [+  testGroup "regular" [+    testCase name $ do+      let mAST = Module "<string>" "<string>" Nothing Nothing [+            GlobalDefinition $ functionDefaults {+              G.returnType = A.T.void,+              G.name = UnName 0,+              G.parameters = ([Parameter t (UnName n) [] | (t,n) <- zip ts [0..]], False),+              G.basicBlocks = [+                BasicBlock (UnName 7) [+                  namedInstr+                 ] (+                  Do $ Ret Nothing []+                 )+               ]+            }+           ]+          mStr = "; ModuleID = '<string>'\n\+                 \source_filename = \"<string>\"\n\+                 \\n\+                 \define void @0(i32, float, i32*, i64, i1, <2 x i32>, { i32, i32 }) {\n\+                 \  " ++ namedInstrS ++ "\n\+                 \  ret void\n\+                 \}\n"+      strCheck mAST mStr+    | let ts = [+           i32,+           float,+           ptr i32,+           i64,+           i1,+           VectorType 2 i32,+           StructureType False [i32, i32]+           ],+      let a i = LocalReference (ts !! fromIntegral i) (UnName i),+      (name, namedInstr, namedInstrS) <- (+        [+         (name, UnName 8 := instr, "%8 = " ++ instrS)+         | (name, instr, instrS) <- [+          ("add",+           Add {+             nsw = False,+             nuw = False,+             operand0 = a 0,+             operand1 = a 0,+             metadata = [] +           },+           "add i32 %0, %0"),+          ("nsw",+           Add {+             nsw = True,+             nuw = False,+             operand0 = a 0,+             operand1 = a 0,+             metadata = [] +           },+           "add nsw i32 %0, %0"),+          ("nuw",+           Add {+             nsw = False,+             nuw = True,+             operand0 = a 0,+             operand1 = a 0,+             metadata = [] +           },+           "add nuw i32 %0, %0"),+          ("fadd",+           FAdd {+             fastMathFlags = NoFastMathFlags,+             operand0 = a 1,+             operand1 = a 1,+             metadata = [] +           },+           "fadd float %1, %1"),+          ("sub",+           Sub {+             nsw = False,+             nuw = False,+             operand0 = a 0,+             operand1 = a 0,+             metadata = [] +           },+           "sub i32 %0, %0"),+          ("fsub",+           FSub {+             fastMathFlags = NoFastMathFlags,+             operand0 = a 1,+             operand1 = a 1,+             metadata = [] +           },+           "fsub float %1, %1"),+          ("mul",+           Mul {+             nsw = False,+             nuw = False,+             operand0 = a 0,+             operand1 = a 0,+             metadata = [] +           },+           "mul i32 %0, %0"),+          ("fmul",+           FMul {+             fastMathFlags = NoFastMathFlags,+             operand0 = a 1,+             operand1 = a 1,+             metadata = [] +           },+           "fmul float %1, %1"),+          ("udiv",+           UDiv {+             exact = False,+             operand0 = a 0,+             operand1 = a 0,+             metadata = [] +           },+           "udiv i32 %0, %0"),+          ("exact",+           UDiv {+             exact = True,+             operand0 = a 0,+             operand1 = a 0,+             metadata = [] +           },+           "udiv exact i32 %0, %0"),+          ("sdiv",+           SDiv {+             exact = False,+             operand0 = a 0,+             operand1 = a 0,+             metadata = [] +           },+           "sdiv i32 %0, %0"),+          ("fdiv",+           FDiv {+             fastMathFlags = NoFastMathFlags,+             operand0 = a 1,+             operand1 = a 1,+             metadata = [] +           },+           "fdiv float %1, %1"),+          ("urem",+           URem {+             operand0 = a 0,+             operand1 = a 0,+             metadata = [] +           },+           "urem i32 %0, %0"),+          ("srem",+           SRem {+             operand0 = a 0,+             operand1 = a 0,+             metadata = [] +           },+           "srem i32 %0, %0"),+          ("frem",+           FRem {+             fastMathFlags = NoFastMathFlags,+             operand0 = a 1,+             operand1 = a 1,+             metadata = [] +           },+           "frem float %1, %1"),+          ("frem fast",+           FRem {+             fastMathFlags = UnsafeAlgebra,+             operand0 = a 1,+             operand1 = a 1,+             metadata = [] +           },+           "frem fast float %1, %1"),+          ("shl",+           Shl {+             nsw = False,+             nuw = False,+             operand0 = a 0,+             operand1 = a 0,+             metadata = [] +           },+           "shl i32 %0, %0"),+          ("ashr",+           AShr {+             exact = False,+             operand0 = a 0,+             operand1 = a 0,+             metadata = [] +           },+           "ashr i32 %0, %0"),+          ("lshr",+           LShr {+             exact = False,+             operand0 = a 0,+             operand1 = a 0,+             metadata = [] +           },+           "lshr i32 %0, %0"),+          ("and",+           And {+             operand0 = a 0,+             operand1 = a 0,+             metadata = [] +           },+           "and i32 %0, %0"),+          ("or",+           Or {+             operand0 = a 0,+             operand1 = a 0,+             metadata = [] +           },+           "or i32 %0, %0"),+          ("xor",+           Xor {+             operand0 = a 0,+             operand1 = a 0,+             metadata = [] +           },+           "xor i32 %0, %0"),+          ("alloca",+           Alloca {+             allocatedType = i32,+             numElements = Nothing,+             alignment = 0,+             metadata = [] +           },+           "alloca i32"),+          ("alloca tricky",+           Alloca {+             allocatedType = IntegerType 7,+             numElements = Just (ConstantOperand (C.Int 32 2)),+             alignment = 128,+             metadata = [] +           },+           "alloca i7, i32 2, align 128"),+          ("load",+           Load {+             volatile = False,+             address = a 2,+             maybeAtomicity = Nothing,+             alignment = 0,+             metadata = [] +           },+           "load i32, i32* %2"),+          ("volatile",+           Load {+             volatile = True,+             address = a 2,+             maybeAtomicity = Nothing,+             alignment = 0,+             metadata = [] +           },+           "load volatile i32, i32* %2"),+          ("acquire",+           Load {+             volatile = False,+             address = a 2,+             maybeAtomicity = Just (CrossThread, Acquire),+             alignment = 1,+             metadata = [] +           },+           "load atomic i32, i32* %2 acquire, align 1"),+          ("singlethread",+           Load {+             volatile = False,+             address = a 2,+             maybeAtomicity = Just (SingleThread, Monotonic),+             alignment = 1,+             metadata = [] +           },+           "load atomic i32, i32* %2 singlethread monotonic, align 1"),+          ("GEP",+           GetElementPtr {+             inBounds = False,+             address = a 2,+             indices = [ a 0 ],+             metadata = [] +           },+           "getelementptr i32, i32* %2, i32 %0"),+          ("inBounds",+           GetElementPtr {+             inBounds = True,+             address = a 2,+             indices = [ a 0 ],+             metadata = [] +           },+           "getelementptr inbounds i32, i32* %2, i32 %0"),+          ("cmpxchg",+           CmpXchg {+             volatile = False,+             address = a 2,+             expected = a 0,+             replacement = a 0,+             atomicity = (CrossThread, Monotonic),+             failureMemoryOrdering = Monotonic,+             metadata = [] +           },+           "cmpxchg i32* %2, i32 %0, i32 %0 monotonic monotonic"),+          ("atomicrmw",+           AtomicRMW {+             volatile = False,+             rmwOperation = RMWOp.UMax,+             address = a 2,+             value = a 0,+             atomicity = (CrossThread, Release),+             metadata = []+           },+           "atomicrmw umax i32* %2, i32 %0 release"),++          ("trunc",+           Trunc {+             operand0 = a 0,+             type' = i16,+             metadata = [] +           },+           "trunc i32 %0 to i16"),+          ("zext",+           ZExt {+             operand0 = a 0,+             type' = i64,+             metadata = [] +           },+           "zext i32 %0 to i64"),+          ("sext",+           SExt {+             operand0 = a 0,+             type' = i64,+             metadata = [] +           },+           "sext i32 %0 to i64"),+          ("fptoui",+           FPToUI {+             operand0 = a 1,+             type' = i64,+             metadata = [] +           },+           "fptoui float %1 to i64"),+          ("fptosi",+           FPToSI {+             operand0 = a 1,+             type' = i64,+             metadata = [] +           },+           "fptosi float %1 to i64"),+          ("uitofp",+           UIToFP {+             operand0 = a 0,+             type' = float,+             metadata = [] +           },+           "uitofp i32 %0 to float"),+          ("sitofp",+           SIToFP {+             operand0 = a 0,+             type' = float,+             metadata = [] +           },+           "sitofp i32 %0 to float"),+          ("fptrunc",+           FPTrunc {+             operand0 = a 1,+             type' = half,+             metadata = [] +           },+           "fptrunc float %1 to half"),+          ("fpext",+           FPExt {+             operand0 = a 1,+             type' = double,+             metadata = [] +           },+           "fpext float %1 to double"),+          ("ptrtoint",+           PtrToInt {+             operand0 = a 2,+             type' = i32,+             metadata = [] +           },+           "ptrtoint i32* %2 to i32"),+          ("inttoptr",+           IntToPtr {+             operand0 = a 0,+             type' = ptr i32,+             metadata = [] +           },+           "inttoptr i32 %0 to i32*"),+          ("bitcast",+           BitCast {+             operand0 = a 0,+             type' = float,+             metadata = [] +           },+           "bitcast i32 %0 to float"),+          ("addrspacecast",+           AddrSpaceCast {+             operand0 = a 2,+             type' = PointerType i32 (AddrSpace 2),+             metadata = [] +           },+           "addrspacecast i32* %2 to i32 addrspace(2)*"),+          ("select",+           Select {+             condition' = a 4,+             trueValue = a 0,+             falseValue = a 0,+             metadata = []+           },+           "select i1 %4, i32 %0, i32 %0"),+          ("vaarg",+           VAArg {+             argList = a 2,+             type' = i16,+             metadata = []+           },+           "va_arg i32* %2, i16"),+          ("extractelement",+           ExtractElement {+             vector = a 5,+             index = a 0,+             metadata = []+           },+           "extractelement <2 x i32> %5, i32 %0"),+          ("insertelement",+           InsertElement {+             vector = a 5,+             element = a 0,+             index = a 0,+             metadata = []+           },+           "insertelement <2 x i32> %5, i32 %0, i32 %0"),+          ("shufflevector",+           ShuffleVector {+             operand0 = a 5,+             operand1 = a 5,+             mask = C.Vector [ C.Int 32 p | p <- [0..1] ],+             metadata = []+           },+           "shufflevector <2 x i32> %5, <2 x i32> %5, <2 x i32> <i32 0, i32 1>"),+          ("extractvalue",+           ExtractValue {+             aggregate = a 6,+             indices' = [0],+             metadata = []+           },+           "extractvalue { i32, i32 } %6, 0"),+          ("insertvalue",+           InsertValue {+             aggregate = a 6,+             element = a 0,+             indices' = [0],+             metadata = []+           },+           "insertvalue { i32, i32 } %6, i32 %0, 0")+         ] ++ [+          ("landingpad-" ++ n,+           LandingPad {+             type' = StructureType False [ +                ptr i8,+                i32+               ],+             cleanup = cp,+             clauses = cls,+             metadata = []+           },+           "landingpad { i8*, i32 }" ++ s)+          | (clsn,cls,clss) <- [+           ("catch",+            [Catch (C.Null (ptr i8))],+            "\n          catch i8* null"),+           ("filter",+            [Filter (C.Null (ArrayType 1 (ptr i8)))],+            "\n          filter [1 x i8*] zeroinitializer")+          ],+          (cpn, cp, cps) <- [ ("-cleanup", True, "\n          cleanup"), ("", False, "") ],+          let s = cps ++ clss+              n = clsn ++ cpn+         ] ++ [+          ("icmp-" ++ ps,+           ICmp { iPredicate = p, operand0 = a 0, operand1 = a 0, metadata = [] },+           "icmp " ++ ps ++ " i32 %0, %0")+           | (ps, p) <- [+           ("eq", IPred.EQ),+           ("ne", IPred.NE),+           ("ugt", IPred.UGT),+           ("uge", IPred.UGE),+           ("ult", IPred.ULT),+           ("ule", IPred.ULE),+           ("sgt", IPred.SGT),+           ("sge", IPred.SGE),+           ("slt", IPred.SLT),+           ("sle", IPred.SLE)+          ]+         ] ++ [+          ("fcmp-" ++ ps,+           FCmp { fpPredicate = p, operand0 = a 1, operand1 = a 1, metadata = [] },+           "fcmp " ++ ps ++ " float %1, %1")+           | (ps, p) <- [+           ("false", FPPred.False),+           ("oeq", FPPred.OEQ),+           ("ogt", FPPred.OGT),+           ("oge", FPPred.OGE),+           ("olt", FPPred.OLT),+           ("ole", FPPred.OLE),+           ("one", FPPred.ONE),+           ("ord", FPPred.ORD),+           ("uno", FPPred.UNO),+           ("ueq", FPPred.UEQ),+           ("ugt", FPPred.UGT),+           ("uge", FPPred.UGE),+           ("ult", FPPred.ULT),+           ("ule", FPPred.ULE),+           ("une", FPPred.UNE),+           ("true", FPPred.True)+          ]+         ]+        ] ++ [+         ("store",+          Do $ Store {+            volatile = False,+            address = a 2,+            value = a 0,+            maybeAtomicity = Nothing,+            alignment = 0,+            metadata = [] +          },+          "store i32 %0, i32* %2"),+         ("fence",+          Do $ Fence {+            atomicity = (CrossThread, Acquire),+            metadata = [] +          },+          "fence acquire"),+          ("call",+           Do $ Call {+             tailCallKind = Nothing,+             callingConvention = CC.C,+             returnAttributes = [],+             function = Right (ConstantOperand (C.GlobalReference (ptr (FunctionType A.T.void ts False)) (UnName 0))),+             arguments = [ (a i, []) | i <- [0..6] ],+             functionAttributes = [],+             metadata = []+           },+           "call void @0(i32 %0, float %1, i32* %2, i64 %3, i1 %4, <2 x i32> %5, { i32, i32 } %6)")+        ]+      )+   ],+  testCase "GEP inBounds constant" $ do+    let mAST = Module "<string>" "<string>" Nothing Nothing [+          GlobalDefinition $ globalVariableDefaults {+            G.name = Name "fortytwo",+            G.type' = i32,+            G.isConstant = True,+            G.initializer = Just $ C.Int 32 42+          },+          GlobalDefinition $ functionDefaults {+            G.returnType = i32,+            G.name = UnName 0,+            G.basicBlocks = [+              BasicBlock (UnName 1) [+                UnName 2 := GetElementPtr {+                  inBounds = True,+                  address = ConstantOperand (C.GlobalReference (ptr i32) (Name "fortytwo")),+                  indices = [ ConstantOperand (C.Int 32 0) ],+                  metadata = []+                },+                UnName 3 := Load {+                  volatile = False,+                  address = LocalReference (ptr i32) (UnName 2),+                  maybeAtomicity = Nothing,+                  alignment = 1,+                  metadata = []+                }+              ] (+                Do $ Ret (Just (LocalReference i32 (UnName 3))) []+              )+             ]+           }+          ]+        mStr = "; ModuleID = '<string>'\n\+               \source_filename = \"<string>\"\n\+               \\n\+               \@0 = constant i32 42\n\+               \\n\+               \define i32 @1() {\n\+               \  %1 = load i32, i32* @0, align 1\n\+               \  ret i32 %1\n\+               \}\n"+    s <- withContext $ \context -> withModuleFromAST' context mAST moduleLLVMAssembly+    s @?= mStr,+    +  testGroup "terminators" [+    testCase name $ strCheck mAST mStr+    | (name, mAST, mStr) <- [+     (+       "ret",+       Module "<string>" "<string>" Nothing Nothing [+        GlobalDefinition $ functionDefaults {+          G.returnType = A.T.void,+          G.name = UnName 0,+          G.basicBlocks = [+            BasicBlock (UnName 0) [+             ] (+              Do $ Ret Nothing []+             )+           ]+         }+        ],+       "; ModuleID = '<string>'\n\+       \source_filename = \"<string>\"\n\+       \\n\+       \define void @0() {\n\+       \  ret void\n\+       \}\n"+     ), (+       "br",+       Module "<string>" "<string>" Nothing Nothing [+        GlobalDefinition $ functionDefaults {+          G.returnType = A.T.void,+          G.name = UnName 0,+          G.basicBlocks = [+            BasicBlock (UnName 0) [] (+              Do $ Br (Name "foo") []+             ),+            BasicBlock (Name "foo") [] (+              Do $ Ret Nothing []+             )+           ]+         }+        ],+       "; ModuleID = '<string>'\n\+       \source_filename = \"<string>\"\n\+       \\n\+       \define void @0() {\n\+       \  br label %foo\n\+       \\n\+       \foo:                                              ; preds = %0\n\+       \  ret void\n\+       \}\n"+     ), (+       "condbr",+       Module "<string>" "<string>" Nothing Nothing [+        GlobalDefinition $ functionDefaults {+          G.returnType = A.T.void,+          G.name = UnName 0,+          G.basicBlocks = [+            BasicBlock (Name "bar") [] (+              Do $ CondBr (ConstantOperand (C.Int 1 1)) (Name "foo") (Name "bar") []+             ),+            BasicBlock (Name "foo") [] (+              Do $ Ret Nothing []+             )+           ]+          }+        ],+       "; ModuleID = '<string>'\n\+       \source_filename = \"<string>\"\n\+       \\n\+       \define void @0() {\n\+       \bar:\n\+       \  br i1 true, label %foo, label %bar\n\+       \\n\+       \foo:                                              ; preds = %bar\n\+       \  ret void\n\+       \}\n"+     ), (+       "switch",+       Module "<string>" "<string>" Nothing Nothing [+         GlobalDefinition $ functionDefaults {+           G.returnType = A.T.void,+           G.name = UnName 0,+           G.basicBlocks = [+             BasicBlock (UnName 0) [] (+               Do $ Switch {+                 operand0' = ConstantOperand (C.Int 16 2),+                 defaultDest = Name "foo",+                 dests = [+                  (C.Int 16 0, UnName 0),+                  (C.Int 16 2, Name "foo"),+                  (C.Int 16 3, UnName 0)+                 ],+                 metadata' = []+              }+             ),+             BasicBlock (Name "foo") [] (+               Do $ Ret Nothing []+              )+            ]+          }+        ],+       "; ModuleID = '<string>'\n\+       \source_filename = \"<string>\"\n\+       \\n\+       \define void @0() {\n\+       \; <label>:0:\n\+       \  switch i16 2, label %foo [\n\+       \    i16 0, label %0\n\+       \    i16 2, label %foo\n\+       \    i16 3, label %0\n\+       \  ]\n\+       \\n\+       \foo:                                              ; preds = %0, %0\n\+       \  ret void\n\+       \}\n"+     ), (+       "indirectbr",+       Module "<string>" "<string>" Nothing Nothing [+        GlobalDefinition $ globalVariableDefaults {+          G.name = UnName 0,+          G.type' = ptr i8,+          G.initializer = Just (C.BlockAddress (Name "foo") (UnName 2))+        },+        GlobalDefinition $ functionDefaults {+          G.returnType = A.T.void,+          G.name = Name "foo",+          G.basicBlocks = [+            BasicBlock (UnName 0) [+              UnName 1 := Load {+                       volatile = False,+                       address = ConstantOperand (C.GlobalReference (ptr (ptr i8)) (UnName 0)),+                       maybeAtomicity = Nothing,+                       alignment = 0,+                       metadata = [] +                     }+            ] (+              Do $ IndirectBr {+                operand0' = LocalReference (ptr i8) (UnName 1),+                possibleDests = [UnName 2],+                metadata' = []+             }+            ),+            BasicBlock (UnName 2) [] (+              Do $ Ret Nothing []+             )+           ]+         }+        ],+--       \  indirectbr i8* null, [label %foo]\n\+       "; ModuleID = '<string>'\n\+       \source_filename = \"<string>\"\n\+       \\n\+       \@0 = global i8* blockaddress(@foo, %2)\n\+       \\n\+       \define void @foo() {\n\+       \  %1 = load i8*, i8** @0\n\+       \  indirectbr i8* %1, [label %2]\n\+       \\n\+       \; <label>:2:                                      ; preds = %0\n\+       \  ret void\n\+       \}\n"+     ), (+       "invoke",+       Module "<string>" "<string>" Nothing Nothing [+        GlobalDefinition $ functionDefaults {+          G.returnType = A.T.void,+          G.name = UnName 0,+          G.personalityFunction = Just $ C.GlobalReference+            (ptr (FunctionType A.T.void [i32,i16] False))+            (UnName 0)+          ,+          G.parameters = ([+            Parameter i32 (UnName 0) [],+            Parameter i16 (UnName 1) []+           ], False),+          G.basicBlocks = [+            BasicBlock (UnName 2) [] (+              Do $ Invoke {+               callingConvention' = CC.C,+               returnAttributes' = [],+               function' = Right (ConstantOperand (C.GlobalReference (ptr (FunctionType A.T.void [i32, i16] False)) (UnName 0))),+               arguments' = [+                (ConstantOperand (C.Int 32 4), []),+                (ConstantOperand (C.Int 16 8), [])+               ],+               functionAttributes' = [],+               returnDest = Name "foo",+               exceptionDest = Name "bar",+               metadata' = []+              }+             ),+            BasicBlock (Name "foo") [] (+              Do $ Ret Nothing []+             ),+            BasicBlock (Name "bar") [+             UnName 3 := LandingPad {+               type' = StructureType False [+                  ptr i8,+                  i32+                 ],+               cleanup = True,+               clauses = [Catch (C.Null (ptr i8))],+               metadata = []+             }+             ] (+              Do $ Ret Nothing []+             )+           ]+         }+        ],+       "; ModuleID = '<string>'\n\+       \source_filename = \"<string>\"\n\+       \\n\+       \define void @0(i32, i16) personality void (i32, i16)* @0 {\n\+       \  invoke void @0(i32 4, i16 8)\n\+       \          to label %foo unwind label %bar\n\+       \\n\+       \foo:                                              ; preds = %2\n\+       \  ret void\n\+       \\n\+       \bar:                                              ; preds = %2\n\+       \  %3 = landingpad { i8*, i32 }\n\+       \          cleanup\n\+       \          catch i8* null\n\+       \  ret void\n\+       \}\n"+      ), (+       "resume",+       Module "<string>" "<string>" Nothing Nothing [+         GlobalDefinition $ functionDefaults {+           G.returnType = A.T.void,+           G.name = UnName 0,+           G.basicBlocks = [+             BasicBlock (UnName 0) [] (+               Do $ Resume (ConstantOperand (C.Int 32 1)) []+              )+            ]+          }+        ],+       "; ModuleID = '<string>'\n\+       \source_filename = \"<string>\"\n\+       \\n\+       \define void @0() {\n\+       \  resume i32 1\n\+       \}\n"+     ), (+       "unreachable",+       Module "<string>" "<string>" Nothing Nothing [+        GlobalDefinition $ functionDefaults {+          G.returnType = A.T.void,+          G.name = UnName 0,+          G.basicBlocks = [+            BasicBlock (UnName 0) [] (+              Do $ Unreachable []+             )+           ]+         }+        ],+       "; ModuleID = '<string>'\n\+       \source_filename = \"<string>\"\n\+       \\n\+       \define void @0() {\n\+       \  unreachable\n\+       \}\n"+     ), ( -- This testcase is taken from test/Feature/exception.ll in LLVM+       "cleanupret0",+       Module {+         moduleName = "<string>",+         moduleSourceFileName = "<string>",+         moduleDataLayout = Nothing,+         moduleTargetTriple = Nothing,+         moduleDefinitions = [+           GlobalDefinition functionDefaults {+             G.returnType = VoidType,+             G.name = Name "_Z3quxv"+           },+           GlobalDefinition functionDefaults {+             G.returnType = IntegerType {typeBits = 32},+             G.name = Name "__gxx_personality_v0",+             G.parameters = ([], True)+           },+           GlobalDefinition functionDefaults {+             G.returnType = VoidType,+             G.name = Name "cleanupret0",+             G.basicBlocks = [+               G.BasicBlock (Name "entry") [] (+                 Do Invoke {+                   callingConvention' = CC.C,+                   returnAttributes' = [],+                   function' = Right (+                     ConstantOperand (+                       C.GlobalReference PointerType {+                         pointerReferent = FunctionType {resultType = VoidType, argumentTypes = [], isVarArg = False},+                         pointerAddrSpace = AddrSpace 0+                       } (Name "_Z3quxv")+                     )+                   ),+                   arguments' = [],+                   returnDest = Name "exit",+                   exceptionDest = Name "pad",+                   metadata' = [],+                   functionAttributes' = []+                 }+               ),+               G.BasicBlock+                 (Name "pad")+                 [Name "cp" := CleanupPad { parentPad = ConstantOperand C.TokenNone, args = [ConstantOperand C.Int { C.integerBits = 7, C.integerValue = 4 }], metadata = [] }]+                 (+                 Do CleanupRet {+                   cleanupPad = LocalReference TokenType (Name "cp"),+                   unwindDest = Nothing,+                   metadata' = []+                 }+                 ),+               G.BasicBlock (Name "exit") [] (Do Ret { returnOperand = Nothing, metadata' = [] })+             ],+             G.personalityFunction = Just (+               C.GlobalReference PointerType {+                 pointerReferent = FunctionType {resultType = IntegerType { typeBits = 32 }, argumentTypes = [], isVarArg = True},+                 pointerAddrSpace = AddrSpace 0+               } (Name "__gxx_personality_v0")+             )+           }+         ]+       },+       "; ModuleID = '<string>'\n\+       \source_filename = \"<string>\"\n\+       \\n\+       \declare void @_Z3quxv()\n\+       \\n\+       \declare i32 @__gxx_personality_v0(...)\n\+       \\n\+       \define void @cleanupret0() personality i32 (...)* @__gxx_personality_v0 {\n\+       \entry:\n\+       \  invoke void @_Z3quxv()\n\+       \          to label %exit unwind label %pad\n\+       \\n\+       \pad:                                              ; preds = %entry\n\+       \  %cp = cleanuppad within none [i7 4]\n\+       \  cleanupret from %cp unwind to caller\n\+       \\n\+       \exit:                                             ; preds = %entry\n\+       \  ret void\n\+       \}\n"+     ), ( -- This testcase is taken from test/Feature/exception.ll in LLVM+       "cleanupret1",+       Module {+         moduleName = "<string>",+         moduleSourceFileName = "<string>",+         moduleDataLayout = Nothing,+         moduleTargetTriple = Nothing,+         moduleDefinitions = [+           GlobalDefinition functionDefaults {+             G.returnType = VoidType,+             G.name = Name "_Z3quxv"+           },+           GlobalDefinition functionDefaults {+             G.returnType = IntegerType {typeBits = 32},+             G.name = Name "__gxx_personality_v0",+             G.parameters = ([], True)+           },+           GlobalDefinition functionDefaults {+             G.returnType = VoidType,+             G.name = Name "cleanupret1",+             G.basicBlocks = [+               G.BasicBlock (Name "entry") [] (+                 Do Invoke {+                   callingConvention' = CC.C,+                   returnAttributes' = [],+                   function' = Right (+                     ConstantOperand (+                       C.GlobalReference PointerType {+                         pointerReferent = FunctionType {resultType = VoidType, argumentTypes = [], isVarArg = False},+                         pointerAddrSpace = AddrSpace 0+                       } (Name "_Z3quxv")+                     )+                   ),+                   arguments' = [],+                   returnDest = Name "exit",+                   exceptionDest = Name "pad",+                   metadata' = [],+                   functionAttributes' = []+                 }+               ),+               G.BasicBlock+                 (Name "cleanup")+                 []+                 (Do CleanupRet {+                    cleanupPad = LocalReference TokenType (Name "cp"),+                    unwindDest = Nothing,+                    metadata' = []+                 }),+               G.BasicBlock+                 (Name "pad")+                 [Name "cp" := CleanupPad { parentPad = ConstantOperand C.TokenNone, args = [], metadata = [] }]+                 (Do Br { dest = Name "cleanup", metadata' = [] }),+               G.BasicBlock (Name "exit") [] (Do Ret { returnOperand = Nothing, metadata' = [] })+             ],+             G.personalityFunction = Just (+               C.GlobalReference PointerType {+                 pointerReferent = FunctionType {resultType = IntegerType { typeBits = 32 }, argumentTypes = [], isVarArg = True},+                 pointerAddrSpace = AddrSpace 0+               } (Name "__gxx_personality_v0")+             )+           }+         ]+       },+       "; ModuleID = '<string>'\n\+       \source_filename = \"<string>\"\n\+       \\n\+       \declare void @_Z3quxv()\n\+       \\n\+       \declare i32 @__gxx_personality_v0(...)\n\+       \\n\+       \define void @cleanupret1() personality i32 (...)* @__gxx_personality_v0 {\n\+       \entry:\n\+       \  invoke void @_Z3quxv()\n\+       \          to label %exit unwind label %pad\n\+       \\n\+       \cleanup:                                          ; preds = %pad\n\+       \  cleanupret from %cp unwind to caller\n\+       \\n\+       \pad:                                              ; preds = %entry\n\+       \  %cp = cleanuppad within none []\n\+       \  br label %cleanup\n\+       \\n\+       \exit:                                             ; preds = %entry\n\+       \  ret void\n\+       \}\n"+     ), ( -- This testcase is taken from test/Feature/exception.ll in LLVM+       "catchret0",+       Module {+         moduleName = "<string>",+         moduleSourceFileName = "<string>",+         moduleDataLayout = Nothing,+         moduleTargetTriple = Nothing,+         moduleDefinitions = [+           GlobalDefinition functionDefaults {+             G.returnType = VoidType,+             G.name = Name "_Z3quxv"+           },+           GlobalDefinition functionDefaults {+             G.returnType = IntegerType {typeBits = 32},+             G.name = Name "__gxx_personality_v0",+             G.parameters = ([], True)+           },+           GlobalDefinition functionDefaults {+             G.returnType = VoidType,+             G.name = Name "catchret0",+             G.basicBlocks = [+               G.BasicBlock (Name "entry") [] (+                 Do Invoke {+                   callingConvention' = CC.C,+                   returnAttributes' = [],+                   function' = Right (+                     ConstantOperand (+                       C.GlobalReference PointerType {+                         pointerReferent = FunctionType {resultType = VoidType, argumentTypes = [], isVarArg = False},+                         pointerAddrSpace = AddrSpace 0+                       } (Name "_Z3quxv")+                     )+                   ),+                   arguments' = [],+                   returnDest = Name "exit",+                   exceptionDest = Name "pad",+                   metadata' = [],+                   functionAttributes' = []+                 }+               ),+               G.BasicBlock (Name "pad") [] (+                 Name "cs1" := CatchSwitch {+                   parentPad' = ConstantOperand C.TokenNone,+                   catchHandlers = (Name "catch" :| []),+                   defaultUnwindDest = Nothing,+                   metadata' = []+                 }+               ),+               G.BasicBlock+                 (Name "catch")+                 [Name "cp" := CatchPad { catchSwitch = LocalReference TokenType (Name "cs1"), args = [ConstantOperand C.Int { C.integerBits = 7, C.integerValue = 4 }], metadata = [] }] (+                 Do CatchRet {+                   catchPad = LocalReference TokenType (Name "cp"),+                   successor = Name "exit",+                   metadata' = []+                 }+               ),+               G.BasicBlock (Name "exit") [] (Do Ret { returnOperand = Nothing, metadata' = [] })+             ],+             G.personalityFunction = Just (+               C.GlobalReference PointerType {+                 pointerReferent = FunctionType {resultType = IntegerType { typeBits = 32 }, argumentTypes = [], isVarArg = True},+                 pointerAddrSpace = AddrSpace 0+               } (Name "__gxx_personality_v0")+             )+           }+         ]+       },+       "; ModuleID = '<string>'\n\+       \source_filename = \"<string>\"\n\+       \\n\+       \declare void @_Z3quxv()\n\+       \\n\+       \declare i32 @__gxx_personality_v0(...)\n\+       \\n\+       \define void @catchret0() personality i32 (...)* @__gxx_personality_v0 {\n\+       \entry:\n\+       \  invoke void @_Z3quxv()\n\+       \          to label %exit unwind label %pad\n\+       \\n\+       \pad:                                              ; preds = %entry\n\+       \  %cs1 = catchswitch within none [label %catch] unwind to caller\n\+       \\n\+       \catch:                                            ; preds = %pad\n\+       \  %cp = catchpad within %cs1 [i7 4]\n\+       \  catchret from %cp to label %exit\n\+       \\n\+       \exit:                                             ; preds = %catch, %entry\n\+       \  ret void\n\+       \}\n"+     ), ( -- This testcase is taken from test/Feature/exception.ll in LLVM+       "catchret1",+       Module {+         moduleName = "<string>",+         moduleSourceFileName = "<string>",+         moduleDataLayout = Nothing,+         moduleTargetTriple = Nothing,+         moduleDefinitions = [+           GlobalDefinition functionDefaults {+             G.returnType = VoidType,+             G.name = Name "_Z3quxv"+           },+           GlobalDefinition functionDefaults {+             G.returnType = IntegerType {typeBits = 32},+             G.name = Name "__gxx_personality_v0",+             G.parameters = ([], True)+           },+           GlobalDefinition functionDefaults {+             G.returnType = VoidType,+             G.name = Name "catchret0",+             G.basicBlocks = [+               G.BasicBlock (Name "entry") [] (+                 Do Invoke {+                   callingConvention' = CC.C,+                   returnAttributes' = [],+                   function' = Right (+                     ConstantOperand (+                       C.GlobalReference PointerType {+                         pointerReferent = FunctionType {resultType = VoidType, argumentTypes = [], isVarArg = False},+                         pointerAddrSpace = AddrSpace 0+                       } (Name "_Z3quxv")+                     )+                   ),+                   arguments' = [],+                   returnDest = Name "exit",+                   exceptionDest = Name "pad",+                   metadata' = [],+                   functionAttributes' = []+                 }+               ),+               G.BasicBlock (Name "catchret") [] (+                 Do CatchRet {+                    catchPad = LocalReference TokenType (Name "cp"),+                    successor = Name "exit",+                    metadata' = []+                 }+               ),+               G.BasicBlock (Name "pad") [] (+                 Name "cs1" := CatchSwitch {+                   parentPad' = ConstantOperand C.TokenNone,+                   catchHandlers = (Name "catch" :| []),+                   defaultUnwindDest = Nothing,+                   metadata' = []+                 }+               ),+               G.BasicBlock+                 (Name "catch")+                 [Name "cp" := CatchPad { catchSwitch = LocalReference TokenType (Name "cs1"), args = [ConstantOperand C.Int { C.integerBits = 7, C.integerValue = 4 }], metadata = [] }] (+                 Do Br { dest = (Name "catchret"), metadata' = [] }+               ),+               G.BasicBlock (Name "exit") [] (Do Ret { returnOperand = Nothing, metadata' = [] })+             ],+             G.personalityFunction = Just (+               C.GlobalReference PointerType {+                 pointerReferent = FunctionType {resultType = IntegerType { typeBits = 32 }, argumentTypes = [], isVarArg = True},+                 pointerAddrSpace = AddrSpace 0+               } (Name "__gxx_personality_v0")+             )+           }+         ]+       },+       "; ModuleID = '<string>'\n\+       \source_filename = \"<string>\"\n\+       \\n\+       \declare void @_Z3quxv()\n\+       \\n\+       \declare i32 @__gxx_personality_v0(...)\n\+       \\n\+       \define void @catchret0() personality i32 (...)* @__gxx_personality_v0 {\n\+       \entry:\n\+       \  invoke void @_Z3quxv()\n\+       \          to label %exit unwind label %pad\n\+       \\n\+       \catchret:                                         ; preds = %catch\n\+       \  catchret from %cp to label %exit\n\+       \\n\+       \pad:                                              ; preds = %entry\n\+       \  %cs1 = catchswitch within none [label %catch] unwind to caller\n\+       \\n\+       \catch:                                            ; preds = %pad\n\+       \  %cp = catchpad within %cs1 [i7 4]\n\+       \  br label %catchret\n\+       \\n\+       \exit:                                             ; preds = %catchret, %entry\n\+       \  ret void\n\+       \}\n"+     )+    ]+   ]+ ]
+ test/LLVM/Test/Instrumentation.hs view
@@ -0,0 +1,159 @@+module LLVM.Test.Instrumentation where++import Test.Tasty+import Test.Tasty.HUnit++import LLVM.Test.Support++import Control.Monad.Trans.Except +import Control.Monad.IO.Class++import Data.Functor hiding (void)+import qualified Data.List as List+import qualified Data.Set as Set+import qualified Data.Map as Map++import LLVM.Module+import LLVM.Context+import LLVM.PassManager+import LLVM.Transforms+import LLVM.Target++import LLVM.AST as A+import LLVM.AST.Type+import LLVM.AST.Name+import LLVM.AST.AddrSpace+import LLVM.AST.DataLayout+import qualified LLVM.AST.IntegerPredicate as IPred+import qualified LLVM.AST.Linkage as L+import qualified LLVM.AST.Visibility as V+import qualified LLVM.AST.CallingConvention as CC+import qualified LLVM.AST.Attribute as A+import qualified LLVM.AST.Global as G+import qualified LLVM.AST.Constant as C++instrument :: PassSetSpec -> A.Module -> IO A.Module+instrument s m = withContext $ \context -> withModuleFromAST' context m $ \mIn' -> do+  withPassManager s $ \pm -> runPassManager pm mIn'+  moduleAST mIn'++ast = do+ dl <- withHostTargetMachine getTargetMachineDataLayout+ triple <- liftIO getDefaultTargetTriple+ return $ Module "<string>" "<string>" (Just dl) (Just triple) [+  -- This function is needed for AddressSanitizerModule+  GlobalDefinition $ functionDefaults {+    G.returnType = void,+    G.name = Name "asan.module_ctor",+    G.basicBlocks = [BasicBlock (UnName 0) [] (Do (Ret Nothing []))]+  },+  GlobalDefinition $ functionDefaults {+    G.returnType = i32,+    G.name = Name "foo",+    G.parameters = ([Parameter i128 (Name "x") []],False),+    G.basicBlocks = [+      BasicBlock (UnName 0) [] (Do $ Br (Name "checkDone") []),+      BasicBlock (Name "checkDone") [+        UnName 1 := Phi {+         type' = i128,+         incomingValues = [+          (LocalReference i128 (Name "x"), UnName 0),+          (LocalReference i128 (Name "x'"), Name "even"),+          (LocalReference i128 (Name "x''"), Name "odd")+         ],+         metadata = []+        },+        Name "count" := Phi {+         type' = i32,+         incomingValues = [+          (ConstantOperand (C.Int 32 1), UnName 0),+          (LocalReference i32 (Name "count'"), Name "even"),+          (LocalReference i32 (Name "count'"), Name "odd")+         ],+         metadata = []+        },+        Name "count'" := Add {+         nsw = False,+         nuw = False,+         operand0 = LocalReference i32 (Name "count"),+         operand1 = ConstantOperand (C.Int 32 1),+         metadata = []+        },+        Name "is one" := ICmp {+         iPredicate = IPred.EQ,+         operand0 = LocalReference i128 (UnName 1),+         operand1 = ConstantOperand (C.Int 128 1),+         metadata = []+        }+      ] (+        Do $ CondBr (LocalReference i1 (Name "is one")) (Name "done") (Name "checkOdd") []+      ),+      BasicBlock (Name "checkOdd") [+        Name "is odd" := Trunc (LocalReference i128 (UnName 1)) i1 []+      ] (+       Do $ CondBr (LocalReference i1 (Name "is odd")) (Name "odd") (Name "even") []+      ),+      BasicBlock (Name "even") [+        Name "x'" := UDiv True (LocalReference i128 (UnName 1)) (ConstantOperand (C.Int 128 2)) []+      ] (+        Do $ Br (Name "checkDone") []+      ),+      BasicBlock (Name "odd") [+        UnName 2 := Mul False False (LocalReference i128 (UnName 1)) (ConstantOperand (C.Int 128 3)) [],+        Name "x''" := Add False False (LocalReference i128 (UnName 2)) (ConstantOperand (C.Int 128 1)) []+      ] (+        Do $ Br (Name "checkDone") []+      ),+      BasicBlock (Name "done") [+      ] (+        Do $ Ret (Just (LocalReference i32 (Name "count'"))) []+      )+     ]+   },+  GlobalDefinition $ functionDefaults {+    G.returnType = i32,+    G.name = Name "main",+    G.parameters = ([+      Parameter i32 (Name "argc") [],+      Parameter (ptr (ptr i8)) (Name "argv") []+     ],False),+    G.basicBlocks = [+      BasicBlock (UnName 0) [+        UnName 1 := Call {+          tailCallKind = Nothing,+          callingConvention = CC.C,+          returnAttributes = [],+          function = Right (ConstantOperand (C.GlobalReference (FunctionType i32 [i32, ptr (ptr i8)] False) (Name "foo"))),+          arguments = [+           (ConstantOperand (C.Int 128 9491828328), [])+          ],+          functionAttributes = [],+          metadata = []+        }+      ] (+        Do $ Ret (Just (LocalReference i32 (UnName 1))) []+      )+     ]+   }+  ]++tests = testGroup "Instrumentation" [+  testGroup "basic" [+    testCase n $ do+      triple <- getProcessTargetTriple +      withTargetLibraryInfo triple $ \tli -> do+        Right dl <- runExceptT $ withHostTargetMachine getTargetMachineDataLayout+        Right ast <- runExceptT ast+        ast' <- instrument (defaultPassSetSpec { transforms = [p], dataLayout = Just dl, targetLibraryInfo = Just tli }) ast+        let names ast = [ n | GlobalDefinition d <- moduleDefinitions ast, Name n <- return (G.name d) ]+        (names ast') `List.intersect` (names ast) @?= names ast+    | (n,p) <- [+     ("GCOVProfiler", defaultGCOVProfiler),+     ("AddressSanitizer", defaultAddressSanitizer),+     ("AddressSanitizerModule", defaultAddressSanitizerModule),+     ("MemorySanitizer", defaultMemorySanitizer),+     ("ThreadSanitizer", defaultThreadSanitizer),+     ("BoundsChecking", BoundsChecking)--,+    ]+   ]+ ]
+ test/LLVM/Test/Linking.hs view
@@ -0,0 +1,66 @@+module LLVM.Test.Linking where++import Test.Tasty+import Test.Tasty.HUnit++import LLVM.Test.Support++import Control.Monad.Trans.Except+import Data.Functor+import qualified Data.Set as Set+import qualified Data.Map as Map++import LLVM.Module+import LLVM.Context+import LLVM.PassManager+import LLVM.Transforms+import LLVM.Target++import LLVM.AST as A+import LLVM.AST.Type+import LLVM.AST.Name+import LLVM.AST.AddrSpace+import LLVM.AST.DataLayout+import qualified LLVM.AST.IntegerPredicate as IPred+import qualified LLVM.AST.Linkage as L+import qualified LLVM.AST.Visibility as V+import qualified LLVM.AST.CallingConvention as CC+import qualified LLVM.AST.Attribute as A+import qualified LLVM.AST.Global as G+import qualified LLVM.AST.Constant as C++tests = testGroup "Linking" [+  testCase "basic" $ do+    let +      ast0 = Module "<string>" "<string>" Nothing Nothing [+          GlobalDefinition $ functionDefaults {+             G.linkage = L.Private,+             G.returnType = i32,+             G.name = Name "private0"+           },+          GlobalDefinition $ functionDefaults {+             G.linkage = L.External,+             G.returnType = i32,+             G.name = Name "external0"+           }+        ]+      ast1 = Module "<string>" "<string>" Nothing Nothing [+          GlobalDefinition $ functionDefaults {+             G.linkage = L.Private,+             G.returnType = i32,+             G.name = Name "private1"+           },+          GlobalDefinition $ functionDefaults {+             G.linkage = L.External,+             G.returnType = i32,+             G.name = Name "external1"+           }+        ]      ++    Module { moduleDefinitions = defs } <- withContext $ \context -> +      withModuleFromAST' context ast0 $ \dest -> do+      withModuleFromAST' context ast0 $ \src -> do+        failInIO $ linkModules dest src+        moduleAST dest+    [ n | GlobalDefinition g <- defs, let Name n = G.name g ] @?= [ "private0", "external0" ]+ ]
+ test/LLVM/Test/Metadata.hs view
@@ -0,0 +1,157 @@+module LLVM.Test.Metadata where++import Test.Tasty+import Test.Tasty.HUnit++import LLVM.Test.Support++import LLVM.AST as A+import LLVM.AST.Type as A.T+import LLVM.AST.AddrSpace as A+import qualified LLVM.AST.Linkage as L+import qualified LLVM.AST.Visibility as V+import qualified LLVM.AST.CallingConvention as CC+import qualified LLVM.AST.Constant as C+import LLVM.AST.Global as G++tests = testGroup "Metadata" [+  -- testCase "local" $ do+  --   let ast = Module "<string>" Nothing Nothing [+  --         GlobalDefinition $ globalVariableDefaults { G.name = UnName 0, G.type' = i32 },+  --         GlobalDefinition $ functionDefaults {+  --           G.returnType = i32,+  --           G.name = Name "foo",+  --           G.basicBlocks = [+  --             BasicBlock (UnName 0) [+  --                UnName 1 := Load {+  --                           volatile = False,+  --                           address = ConstantOperand (C.GlobalReference (ptr i32) (UnName 0)),+  --                           maybeAtomicity = Nothing,+  --                           A.alignment = 0,+  --                           metadata = []+  --                         }+  --                ] (+  --                Do $ Ret (Just (ConstantOperand (C.Int 32 0))) [+  --                  (+  --                    "my-metadatum", +  --                    MetadataNode [+  --                     Just $ MDValue $ LocalReference i32 (UnName 1),+  --                     Just $ MDString "super hyper",+  --                     Nothing+  --                    ]+  --                  )+  --                ]+  --              )+  --            ]+  --          }+  --        ]+  --   let s = "; ModuleID = '<string>'\n\+  --           \\n\+  --           \@0 = external global i32\n\+  --           \\n\+  --           \define i32 @foo() {\n\+  --           \  %1 = load i32, i32* @0\n\+  --           \  ret i32 0, !my-metadatum !{i32 %1, !\"super hyper\", null}\n\+  --           \}\n"+  --   strCheck ast s,++  testCase "global" $ do+    let ast = Module "<string>" "<string>" Nothing Nothing [+          GlobalDefinition $ functionDefaults {+            G.returnType = i32,+            G.name = Name "foo",+            G.basicBlocks = [+              BasicBlock (UnName 0) [+              ] (+                Do $ Ret (Just (ConstantOperand (C.Int 32 0))) [+                  ("my-metadatum", MetadataNodeReference (MetadataNodeID 0))+                ]+              )+             ]+            },+          MetadataNodeDefinition (MetadataNodeID 0) [ Just $ MDValue $ ConstantOperand (C.Int 32 1) ]+         ]+    let s = "; ModuleID = '<string>'\n\+            \source_filename = \"<string>\"\n\+            \\n\+            \define i32 @foo() {\n\+            \  ret i32 0, !my-metadatum !0\n\+            \}\n\+            \\n\+            \!0 = !{i32 1}\n"+    strCheck ast s,++  testCase "named" $ do+    let ast = Module "<string>" "<string>" Nothing Nothing [+          NamedMetadataDefinition "my-module-metadata" [ MetadataNodeID 0 ],+          MetadataNodeDefinition (MetadataNodeID 0) [ Just $ MDValue $ ConstantOperand (C.Int 32 1) ]+         ]+    let s = "; ModuleID = '<string>'\n\+            \source_filename = \"<string>\"\n\+            \\n\+            \!my-module-metadata = !{!0}\n\+            \\n\+            \!0 = !{i32 1}\n"+    strCheck ast s,++  testCase "null" $ do+    let ast = Module "<string>" "<string>" Nothing Nothing [+          NamedMetadataDefinition "my-module-metadata" [ MetadataNodeID 0 ],+          MetadataNodeDefinition (MetadataNodeID 0) [ Nothing ]+         ]+    let s = "; ModuleID = '<string>'\n\+            \source_filename = \"<string>\"\n\+            \\n\+            \!my-module-metadata = !{!0}\n\+            \\n\+            \!0 = !{null}\n"+    strCheck ast s,++  testGroup "cyclic" [+    testCase "metadata-only" $ do+      let ast = Module "<string>" "<string>" Nothing Nothing [+            NamedMetadataDefinition "my-module-metadata" [MetadataNodeID 0],+            MetadataNodeDefinition (MetadataNodeID 0) [+              Just $ MDNode (MetadataNodeReference (MetadataNodeID 1)) +             ],+            MetadataNodeDefinition (MetadataNodeID 1) [+              Just $ MDNode (MetadataNodeReference (MetadataNodeID 0)) +             ]+           ]+      let s = "; ModuleID = '<string>'\n\+              \source_filename = \"<string>\"\n\+              \\n\+              \!my-module-metadata = !{!0}\n\+              \\n\+              \!0 = !{!1}\n\+              \!1 = !{!0}\n"+      strCheck ast s,++    testCase "metadata-global" $ do+      let ast = Module "<string>" "<string>" Nothing Nothing [+            GlobalDefinition $ functionDefaults {+              G.returnType = A.T.void,+              G.name = Name "foo",+              G.basicBlocks = [+                BasicBlock (UnName 0) [+                 ] (+                   Do $ Ret Nothing [ ("my-metadatum", MetadataNodeReference (MetadataNodeID 0)) ]+                 )+               ]+             },+            MetadataNodeDefinition (MetadataNodeID 0) [+              Just $ MDValue $ ConstantOperand (C.GlobalReference (ptr (FunctionType A.T.void [] False)) (Name "foo"))+             ]+           ]+      let s = "; ModuleID = '<string>'\n\+              \source_filename = \"<string>\"\n\+              \\n\+              \define void @foo() {\n\+              \  ret void, !my-metadatum !0\n\+              \}\n\+              \\n\+              \!0 = !{void ()* @foo}\n"+      strCheck ast s+   ]++ ]
+ test/LLVM/Test/Module.hs view
@@ -0,0 +1,574 @@+module LLVM.Test.Module where++import Test.Tasty+import Test.Tasty.HUnit++import LLVM.Test.Support++import Control.Monad.Trans.Except+import Data.Bits+import Data.Word++import qualified Data.Map as Map++import LLVM.Context+import LLVM.Module+import LLVM.Analysis+import LLVM.Diagnostic+import LLVM.Target+import LLVM.AST+import LLVM.AST.Type as T+import LLVM.AST.AddrSpace+import qualified LLVM.AST.IntegerPredicate as IPred++import qualified LLVM.AST.Linkage as L+import qualified LLVM.AST.Visibility as V+import qualified LLVM.AST.DLL as DLL+import qualified LLVM.AST.CallingConvention as CC+import qualified LLVM.AST.FunctionAttribute as FA+import qualified LLVM.AST.ParameterAttribute as PA+import qualified LLVM.AST.ThreadLocalStorage as TLS+import qualified LLVM.AST.Global as G+import qualified LLVM.AST.Constant as C+import qualified LLVM.AST.COMDAT as COMDAT++import qualified LLVM.Relocation as R+import qualified LLVM.CodeModel as CM+import qualified LLVM.CodeGenOpt as CGO++handString = "; ModuleID = '<string>'\n\+    \source_filename = \"<string>\"\n\+    \\n\+    \%0 = type { i32, %1*, %0* }\n\+    \%1 = type opaque\n\+    \\n\+    \$bob = comdat largest\n\+    \\n\+    \@0 = global i32 1\n\+    \@1 = external protected addrspace(3) global i32, section \"foo\", comdat($bob)\n\+    \@2 = unnamed_addr global i8 2\n\+    \@3 = external dllimport global %0\n\+    \@4 = external global [4294967296 x i32]\n\+    \@.argyle = thread_local global i32 0\n\+    \@5 = thread_local(localdynamic) global i32 1\n\+    \\n\+    \@three = private alias i32, i32 addrspace(3)* @1\n\+    \@two = unnamed_addr alias i32, i32 addrspace(3)* @three\n\+    \@one = thread_local(initialexec) alias i32, i32* @5\n\+    \\n\+    \define i32 @bar() prefix i32 1 {\n\+    \  %1 = musttail call zeroext i32 @foo(i32 inreg align 16 1, i8 signext 4) #0\n\+    \  ret i32 %1\n\+    \}\n\+    \\n\+    \; Function Attrs: nounwind readnone uwtable\n\+    \define zeroext i32 @foo(i32 inreg align 16 %x, i8 signext %y) #0 {\n\+    \  %1 = mul nsw i32 %x, %x\n\+    \  br label %here\n\+    \\n\+    \here:                                             ; preds = %0\n\+    \  %go = icmp eq i32 %1, %x\n\+    \  br i1 %go, label %there, label %elsewhere\n\+    \\n\+    \there:                                            ; preds = %here\n\+    \  %2 = add nsw i32 %1, 3\n\+    \  br label %elsewhere\n\+    \\n\+    \elsewhere:                                        ; preds = %there, %here\n\+    \  %r = phi i32 [ 2, %there ], [ 57, %here ]\n\+    \  ret i32 %r\n\+    \}\n\+    \\n\+    \attributes #0 = { nounwind readnone uwtable \"eep\" }\n"++handAST = Module "<string>" "<string>" Nothing Nothing [+      TypeDefinition (UnName 0) (+         Just $ StructureType False [+           i32,+           ptr (NamedTypeReference (UnName 1)),+           ptr (NamedTypeReference (UnName 0))+          ]),+      TypeDefinition (UnName 1) Nothing,+      GlobalDefinition $ globalVariableDefaults {+        G.name = UnName 0,+        G.type' = i32,+        G.initializer = Just (C.Int 32 1)+      },+      GlobalDefinition $ globalVariableDefaults {+        G.name = UnName 1,+        G.visibility = V.Protected,+        G.type' = i32,+        G.addrSpace = AddrSpace 3,+        G.section = Just "foo",+        G.comdat = Just "bob"+      },+      GlobalDefinition $ globalVariableDefaults {+        G.name = UnName 2,+        G.unnamedAddr = Just GlobalAddr,+        G.type' = i8,+        G.initializer = Just (C.Int 8 2)+      },+      GlobalDefinition $ globalVariableDefaults {+        G.name = UnName 3,+        G.dllStorageClass = Just DLL.Import,+        G.type' = NamedTypeReference (UnName 0)+      },+      GlobalDefinition $ globalVariableDefaults {+        G.name = UnName 4,+        G.type' = ArrayType (1 `shift` 32) i32+      },+      GlobalDefinition $ globalVariableDefaults {+        G.name = Name ".argyle",+        G.type' = i32,+        G.initializer = Just (C.Int 32 0),+        G.threadLocalMode = Just TLS.GeneralDynamic+      },+      GlobalDefinition $ globalVariableDefaults {+        G.name = UnName 5,+        G.type' = i32,+        G.threadLocalMode = Just TLS.LocalDynamic,+        G.initializer = Just (C.Int 32 1)+      },+      GlobalDefinition $ globalAliasDefaults {+         G.name = Name "three",+         G.linkage = L.Private,+         G.type' = PointerType i32 (AddrSpace 3),+         G.aliasee = C.GlobalReference (PointerType i32 (AddrSpace 3)) (UnName 1)+      },+      GlobalDefinition $ globalAliasDefaults {+        G.name = Name "two",+        G.unnamedAddr = Just GlobalAddr,+        G.type' = PointerType i32 (AddrSpace 3),+        G.aliasee = C.GlobalReference (PointerType i32 (AddrSpace 3)) (Name "three")+      },+      GlobalDefinition $ globalAliasDefaults {+        G.name = Name "one",+        G.type' = ptr i32,+        G.aliasee = C.GlobalReference (ptr i32) (UnName 5),+        G.threadLocalMode = Just TLS.InitialExec+      },+      GlobalDefinition $ functionDefaults {+        G.returnType = i32,+        G.name = Name "bar",+        G.prefix = Just (C.Int 32 1),+        G.basicBlocks = [+          BasicBlock (UnName 0) [+           UnName 1 := Call {+             tailCallKind = Just MustTail,+             callingConvention = CC.C,+             returnAttributes = [PA.ZeroExt],+             function = Right (ConstantOperand (C.GlobalReference (ptr (FunctionType i32 [i32, i8] False)) (Name "foo"))),+             arguments = [+              (ConstantOperand (C.Int 32 1), [PA.InReg, PA.Alignment 16]),+              (ConstantOperand (C.Int 8 4), [PA.SignExt])+             ],+             functionAttributes = [Left (FA.GroupID 0)],+             metadata = []+           }+         ] (+           Do $ Ret (Just (LocalReference i32 (UnName 1))) []+         )+        ]+      },+      GlobalDefinition $ functionDefaults {+        G.returnAttributes = [PA.ZeroExt],+        G.returnType = i32,+        G.name = Name "foo",+        G.parameters = ([+          Parameter i32 (Name "x") [PA.InReg, PA.Alignment 16],+          Parameter i8 (Name "y") [PA.SignExt]+         ], False),+        G.functionAttributes = [Left (FA.GroupID 0)],+        G.basicBlocks = [+          BasicBlock (UnName 0) [+           UnName 1 := Mul {+             nsw = True,+             nuw = False,+             operand0 = LocalReference i32 (Name "x"),+             operand1 = LocalReference i32 (Name "x"),+             metadata = []+           }+           ] (+             Do $ Br (Name "here") []+           ),+          BasicBlock (Name "here") [+           Name "go" := ICmp {+             iPredicate = IPred.EQ,+             operand0 = LocalReference i32 (UnName 1),+             operand1 = LocalReference i32 (Name "x"),+             metadata = []+           }+           ] (+              Do $ CondBr {+                condition = LocalReference i1 (Name "go"),+                trueDest = Name "there",+                falseDest = Name "elsewhere",+                metadata' = []+              }+           ),+          BasicBlock (Name "there") [+           UnName 2 := Add {+             nsw = True,+             nuw = False,+             operand0 = LocalReference i32 (UnName 1),+             operand1 = ConstantOperand (C.Int 32 3),+             metadata = []+           }+           ] (+             Do $ Br (Name "elsewhere") []+           ),+          BasicBlock (Name "elsewhere") [+           Name "r" := Phi {+             type' = i32,+             incomingValues = [+               (ConstantOperand (C.Int 32 2), Name "there"),+               (ConstantOperand (C.Int 32 57), Name "here")+             ],+             metadata = []+           }+           ] (+             Do $ Ret (Just (LocalReference i32 (Name "r"))) []+           )+         ]+        },+      FunctionAttributes (FA.GroupID 0) [FA.NoUnwind, FA.ReadNone, FA.UWTable, FA.StringAttribute "eep" ""],+      COMDAT "bob" COMDAT.Largest+     ]++tests = testGroup "Module" [+  testGroup "withModuleFromString" [+    testCase "basic" $ withContext $ \context -> do+      z <- withModuleFromLLVMAssembly' context handString (const $ return 0)+      z @?= 0,+    testCase "numbering" $ withContext $ \context -> do+      let s = "@0 = global i32 3\+              \define i32 @1(i32 %x) {\n\+              \  %1 = mul i32 %x, %x\n\+              \  %2 = add i32 %1, 3\n\+              \  ret i32 %2\n\+              \}\n"+      z <- withModuleFromLLVMAssembly' context s (const $ return 0)+      z @?= 0+   ],++  testGroup "emit" [+    testCase "assemble" $ withContext $ \context -> do+      let s = "define i32 @main(i32 %argc, i8** %argv) {\n\+              \  ret i32 0\n\+              \}\n"+      a <- withModuleFromLLVMAssembly' context s $ \m -> do+        (t, _) <- failInIO $ lookupTarget Nothing "x86_64-unknown-linux"+        withTargetOptions $ \to -> do+          withTargetMachine t "x86_64-unknown-linux" "" Map.empty to R.Default CM.Default CGO.Default $ \tm -> do+            failInIO $ moduleTargetAssembly tm m+      a @?= "\t.text\n\+            \\t.file\t\"<string>\"\n\+            \\t.globl\tmain\n\+            \\t.p2align\t4, 0x90\n\+            \\t.type\tmain,@function\n\+            \main:\n\+            \\t.cfi_startproc\n\+            \\txorl\t%eax, %eax\n\+            \\tretq\n\+            \.Lfunc_end0:\n\+            \\t.size\tmain, .Lfunc_end0-main\n\+            \\t.cfi_endproc\n\+            \\n\+            \\n\+            \\t.section\t\".note.GNU-stack\",\"\",@progbits\n"+   ],++  testCase "handStringIsCanonical" $ withContext $ \context -> do+    s <- withModuleFromLLVMAssembly' context handString moduleLLVMAssembly+    s @?= handString,++  testCase "moduleAST" $ withContext $ \context -> do+    ast <- withModuleFromLLVMAssembly' context handString moduleAST+    ast @?= handAST,+    +  testCase "withModuleFromAST" $ withContext $ \context -> do+    s <- withModuleFromAST' context handAST moduleLLVMAssembly+    s @?= handString,++  testCase "bitcode" $ withContext $ \context -> do+    bs <- withModuleFromAST' context handAST moduleBitcode+    s <- withModuleFromBitcode' context bs moduleLLVMAssembly+    s @?= handString,++  testCase "triple" $ withContext $ \context -> do+   let hAST = "; ModuleID = '<string>'\n\+              \target triple = \"x86_64-unknown-linux\"\n"+   ast <- withModuleFromLLVMAssembly' context hAST moduleAST+   ast @?= defaultModule { moduleTargetTriple = Just "x86_64-unknown-linux" },++  testGroup "regression" [+    testCase "minimal type info" $ withContext $ \context -> do+      let s = "; ModuleID = '<string>'\n\+              \source_filename = \"<string>\"\n\+              \\n\+              \define void @trouble() {\n\+              \entry:\n\+              \  ret void\n\+              \\n\+              \dead0:                                            ; preds = %dead1\n\+              \  %x0 = add i32 %x1, %x1\n\+              \  br label %dead1\n\+              \\n\+              \dead1:                                            ; preds = %dead0\n\+              \  %x1 = add i32 %x0, %x0\n\+              \  br label %dead0\n\+              \}\n"+          ast = Module "<string>" "<string>" Nothing Nothing [+             GlobalDefinition $ functionDefaults {+                G.returnType = T.void,+                G.name = Name "trouble",+                G.basicBlocks = [+                 BasicBlock (Name "entry") [+                  ] (+                   Do $ Ret Nothing []+                  ),+                 BasicBlock (Name "dead0") [+                   Name "x0" := Add {+                     nsw = False,+                     nuw = False,+                     operand0 = LocalReference i32 (Name "x1"),+                     operand1 = LocalReference i32 (Name "x1"),+                     metadata = []+                   }+                  ] (+                   Do $ Br (Name "dead1") []+                  ),+                 BasicBlock (Name "dead1") [+                   Name "x1" := Add {+                     nsw = False,+                     nuw = False,+                     operand0 = LocalReference i32 (Name "x0"),+                     operand1 = LocalReference i32 (Name "x0"),+                     metadata = []+                   }+                  ] (+                   Do $ Br (Name "dead0") []+                  )+                 ]+              }+            ]+      strCheck ast s+      s' <- withContext $ \context -> withModuleFromAST' context ast $ runExceptT . verify+      s' @?= Right (),++    testCase "metadata type" $ withContext $ \context -> do+      let s = "; ModuleID = '<string>'\n\+              \source_filename = \"<string>\"\n\+              \\n\+              \define void @bar(metadata) {\n\+              \  ret void\n\+              \}\n"+          ast = Module "<string>" "<string>" Nothing Nothing [+             GlobalDefinition $ functionDefaults {+               G.returnType = void,+               G.name = Name "bar",+               G.parameters = ([Parameter MetadataType (UnName 0) []], False),+               G.basicBlocks = [+                 BasicBlock (UnName 1) [] (Do $ Ret Nothing [])+                ]+             }+           ]+      strCheck ast s,++    testCase "set flag on constant expr" $ withContext $ \context -> do+      let ast = Module "<string>" "<string>" Nothing Nothing [+             GlobalDefinition $ functionDefaults {+               G.returnType = i32,+               G.name = Name "foo",+               G.parameters = ([Parameter i32 (Name "x") []], False),+               G.basicBlocks = [+                 BasicBlock (UnName 0) [+                  UnName 1 := Mul {+                    nsw = True,+                    nuw = False,+                    operand0 = ConstantOperand (C.Int 32 1),+                    operand1 = ConstantOperand (C.Int 32 1),+                    metadata = []+                  }+                  ] (+                    Do $ Br (Name "here") []+                  ),+                 BasicBlock (Name "here") [+                  ] (+                    Do $ Ret (Just (LocalReference i32 (UnName 1))) []+                  )+                ]+             }+           ]+      t <- withModuleFromAST' context ast $ \_ -> return True+      t @?= True,++    testCase "Phi node finishes" $ withContext $ \context -> do+      let ast = Module "<string>" "<string>" Nothing Nothing [+            GlobalDefinition $ functionDefaults {+              G.returnType = i32,+              G.name = Name "foo",+              G.parameters = ([Parameter i32 (Name "x") []], False),+              G.basicBlocks = [+                BasicBlock (UnName 0) [+                 UnName 1 := Mul {+                   nsw = True,+                   nuw = False,+                   operand0 = LocalReference i32 (Name "x"),+                   operand1 = LocalReference i32 (Name "x"),+                   metadata = []+                 }+                 ] (+                   Do $ Br (Name "here") []+                 ),+                BasicBlock (Name "here") [+                 UnName 2 := Phi i32 [ (ConstantOperand (C.Int 32 42), UnName 0) ] []+                 ] (+                   Do $ Br (Name "elsewhere") []+                 ),+                BasicBlock (Name "elsewhere") [             +                 ] (+                   Do $ Br (Name "there") []+                 ),+                BasicBlock (Name "there") [+                 ] (+                   Do $ Ret (Just (LocalReference i32 (UnName 1))) []+                 )+               ]+             }+           ]+          s = "; ModuleID = '<string>'\n\+              \source_filename = \"<string>\"\n\+              \\n\+              \define i32 @foo(i32 %x) {\n\+              \  %1 = mul nsw i32 %x, %x\n\+              \  br label %here\n\+              \\n\+              \here:                                             ; preds = %0\n\+              \  %2 = phi i32 [ 42, %0 ]\n\+              \  br label %elsewhere\n\+              \\n\+              \elsewhere:                                        ; preds = %here\n\+              \  br label %there\n\+              \\n\+              \there:                                            ; preds = %elsewhere\n\+              \  ret i32 %1\n\+              \}\n"+      strCheck ast s,++      testCase "switchblock" $ do+        let count = 450+            start = 2 -- won't come back the same w/o start = 2+            ns = [start..count + start - 1]+            vbps = zip [ ConstantOperand (C.Int 32 i) | i <- [0..] ] [ UnName n | n <- (1:ns) ]+            cbps = zip [ C.Int 32 i | i <- [0..] ] [ UnName n | n <- ns ]++        withContext $ \context -> do+          let ast = Module "<string>" "<string>" Nothing Nothing [+                GlobalDefinition $ functionDefaults {+                  G.name = Name "foo",+                  G.returnType = i32,+                  G.parameters = ([Parameter i32 (UnName 0) []], False),+                  G.basicBlocks = [+                   BasicBlock (UnName 1) [] (Do $ Switch (LocalReference i32 (UnName 0)) (Name "end") cbps [])+                  ] ++ [+                   BasicBlock (UnName n) [] (Do $ Br (Name "end") []) | n <- ns+                  ] ++ [+                   BasicBlock (Name "end") [+                     Name "val" := Phi i32 vbps []+                   ] (+                     Do $ Ret (Just (LocalReference i32 (Name "val"))) []+                   )+                  ]+                }+               ]+          s <- withModuleFromAST' context ast moduleLLVMAssembly+          m <- withModuleFromLLVMAssembly' context s moduleAST+          m @?= ast,++      testCase "struct constant" $ do+        let s = "; ModuleID = '<string>'\n\+                \source_filename = \"<string>\"\n\+                \\n\+                \%0 = type { i32 }\n\+                \\n\+                \@0 = constant %0 { i32 1 }, align 4\n"+            ast = Module "<string>" "<string>" Nothing Nothing [+              TypeDefinition (UnName 0) (Just $ StructureType False [i32]),+              GlobalDefinition $ globalVariableDefaults {+                G.name = UnName 0,+                G.isConstant = True,+                G.type' = NamedTypeReference (UnName 0),+                G.initializer = Just $ C.Struct (Just $ UnName 0) False [ C.Int 32 1 ],+                G.alignment = 4+              }+             ]+        strCheck ast s+   ],+        +  testGroup "failures" [+    testCase "bad block reference" $ withContext $ \context -> do+      let badAST = Module "<string>" "<string>" Nothing Nothing [+            GlobalDefinition $ functionDefaults {+              G.returnType = i32,+              G.name = Name "foo",+              G.parameters = ([Parameter i32 (Name "x") []], False),+              G.basicBlocks = [+                BasicBlock (UnName 0) [+                 UnName 1 := Mul {+                   nsw = True,+                   nuw = False,+                   operand0 = ConstantOperand (C.Int 32 1),+                   operand1 = ConstantOperand (C.Int 32 1),+                   metadata = []+                 }+                 ] (+                   Do $ Br (Name "not here") []+                 ),+                BasicBlock (Name "here") [+                 ] (+                   Do $ Ret (Just (LocalReference i32 (UnName 1))) []+                 )+               ]+             }+           ]+      t <- runExceptT $ withModuleFromAST context badAST $ \_ -> return True+      t @?= Left "reference to undefined block: Name \"not here\"",++    testCase "multiple" $ withContext $ \context -> do+      let badAST = Module "<string>" "<string>" Nothing Nothing [+            GlobalDefinition $ functionDefaults {+              G.returnType = i32,+              G.name = Name "foo",+              G.basicBlocks = [+                BasicBlock (UnName 0) [+                 UnName 1 := Mul {+                   nsw = False,+                   nuw = False,+                   operand0 = LocalReference i32 (Name "unknown"),+                   operand1 = ConstantOperand (C.Int 32 1),+                   metadata = []+                 },+                 UnName 2 := Mul {+                   nsw = False,+                   nuw = False,+                   operand0 = LocalReference i32 (Name "unknown2"),+                   operand1 = LocalReference i32 (UnName 1),+                   metadata = []+                 }+                 ] (+                   Do $ Ret (Just (LocalReference i32 (UnName 2))) []+                 )+               ]+             }+           ]+      t <- runExceptT $ withModuleFromAST context badAST $ \_ -> return True+      t @?= Left "reference to undefined local: Name \"unknown\"",++    testCase "sourceFileName" $ withContext $ \context -> do+      let s = "; ModuleID = '<string>'\n\+              \source_filename = \"filename\"\n"+          ast = Module "<string>" "filename" Nothing Nothing []+      strCheck ast s+   ]+ ]
+ test/LLVM/Test/ObjectCode.hs view
@@ -0,0 +1,35 @@+module LLVM.Test.ObjectCode where++import Test.Tasty+import Test.Tasty.HUnit++import LLVM.Test.Support++import qualified Data.ByteString as ByteString+import System.IO+import System.IO.Temp++import LLVM.Context+import LLVM.Module+import LLVM.Target++ll :: String+ll = unlines ["define i32 @main(i32 %argc, i8** %argv) {", "  ret i32 0", "}"]++tests =+  testGroup+    "Object code serialization"+    [ testCase+        "serialization to ByteString and to file" $ do+        withContext $ \ctx ->+          withSystemTempFile "foo" $ \objFile handle -> do+            hClose handle+            failInIO $+              withHostTargetMachine $ \machine ->+                failInIO $+                withModuleFromLLVMAssembly ctx ll $ \mdl -> do+                  obj <- failInIO $ moduleObject machine mdl+                  _ <- failInIO $ writeObjectToFile machine (File objFile) mdl+                  obj' <- ByteString.readFile objFile+                  obj @=? obj'+    ]
+ test/LLVM/Test/Optimization.hs view
@@ -0,0 +1,306 @@+module LLVM.Test.Optimization where++import Test.Tasty+import Test.Tasty.HUnit++import LLVM.Test.Support++import Data.Functor+import qualified Data.Set as Set+import qualified Data.Map as Map++import LLVM.Module+import LLVM.Context+import LLVM.PassManager+import qualified LLVM.Transforms as T+import LLVM.Target++import LLVM.AST as A+import LLVM.AST.Type as A.T+import LLVM.AST.Name+import LLVM.AST.AddrSpace+import LLVM.AST.DataLayout+import qualified LLVM.AST.IntegerPredicate as IPred+import qualified LLVM.AST.Linkage as L+import qualified LLVM.AST.Visibility as V+import qualified LLVM.AST.CallingConvention as CC+import qualified LLVM.AST.Attribute as A+import qualified LLVM.AST.Global as G+import qualified LLVM.AST.Constant as C++import qualified LLVM.Relocation as R+import qualified LLVM.CodeModel as CM+import qualified LLVM.CodeGenOpt as CGO++handAST = +  Module "<string>" "<string>" Nothing Nothing [+      GlobalDefinition $ functionDefaults {+        G.returnType = i32,+        G.name = Name "foo",+        G.parameters = ([Parameter i32 (Name "x") []], False),+        G.functionAttributes = [Left (A.GroupID 0)],+        G.basicBlocks = [+          BasicBlock (UnName 0) [+           UnName 1 := Mul {+             nsw = False,+             nuw = False,+             operand0 = ConstantOperand (C.Int 32 6),+             operand1 = ConstantOperand (C.Int 32 7),+             metadata = []+           }+           ] (+             Do $ Br (Name "here") []+           ),+          BasicBlock (Name "here") [+           Name "go" := ICmp {+             iPredicate = IPred.EQ,+             operand0 = LocalReference i32 (UnName 1),+             operand1 = ConstantOperand (C.Int 32 42),+             metadata = []+           }+           ] (+              Do $ CondBr {+                condition = LocalReference i1 (Name "go"),+                trueDest = Name "take",+                falseDest = Name "done",+                metadata' = []+              }+           ),+          BasicBlock (Name "take") [+           UnName 2 := Sub {+             nsw = False,+             nuw = False,+             operand0 = LocalReference i32 (Name "x"),+             operand1 = LocalReference i32 (Name "x"),+             metadata = []+           }+           ] (+             Do $ Br (Name "done") []+           ),+          BasicBlock (Name "done") [+           Name "r" := Phi {+             type' = i32,+             incomingValues = [+               (LocalReference i32 (UnName 2), Name "take"),+               (ConstantOperand (C.Int 32 57), Name "here")+             ],+             metadata = []+           }+           ] (+             Do $ Ret (Just (LocalReference i32 (Name "r"))) []+           )+         ]+       },+      FunctionAttributes (A.GroupID 0) [A.NoUnwind, A.ReadNone, A.UWTable]+     ]++isVectory :: A.Module -> Assertion+isVectory Module { moduleDefinitions = ds } =+  (@? "Module is not vectory") $ not $ null [ i +    | GlobalDefinition (Function { G.basicBlocks = b }) <- ds,+      BasicBlock _ is _ <- b,+      _ := i@(ExtractElement {}) <- is+   ]++optimize :: PassSetSpec -> A.Module -> IO A.Module+optimize pss m = withContext $ \context -> withModuleFromAST' context m $ \mIn' -> do+  withPassManager pss $ \pm -> runPassManager pm mIn'+  moduleAST mIn'++tests = testGroup "Optimization" [+  testCase "curated" $ do+    mOut <- optimize defaultCuratedPassSetSpec handAST++    mOut @?= Module "<string>" "<string>" Nothing Nothing [+      GlobalDefinition $ functionDefaults {+        G.returnType = i32,+         G.name = Name "foo",+         G.parameters = ([Parameter i32 (Name "x") []], False),+         G.functionAttributes = [Left (A.GroupID 0)],+         G.basicBlocks = [+           BasicBlock (Name "here") [+              ] (+              Do $ Ret (Just (ConstantOperand (C.Int 32 0))) []+            )+          ]+        },+      FunctionAttributes (A.GroupID 0) [A.NoRecurse, A.NoUnwind, A.ReadNone, A.UWTable]+      ],++  testGroup "individual" [+    testCase "ConstantPropagation" $ do+      mOut <- optimize defaultPassSetSpec { transforms = [T.ConstantPropagation] } handAST++      mOut @?= Module "<string>" "<string>" Nothing Nothing [+        GlobalDefinition $ functionDefaults {+          G.returnType = i32,+          G.name = Name "foo",+          G.parameters = ([Parameter i32 (Name "x") []], False),+          G.functionAttributes = [Left (A.GroupID 0)],+          G.basicBlocks = [+            BasicBlock (UnName 0) [] (Do $ Br (Name "here") []),+            BasicBlock (Name "here") [] (+               Do $ CondBr {+                 condition = ConstantOperand (C.Int 1 1),+                 trueDest = Name "take", +                 falseDest = Name "done",+                 metadata' = []+               }+            ),+            BasicBlock (Name "take") [+             UnName 1 := Sub {+               nsw = False,+               nuw = False,+               operand0 = LocalReference i32 (Name "x"),+               operand1 = LocalReference i32 (Name "x"),+               metadata = []+              }+            ] (+             Do $ Br (Name "done") []+            ),+            BasicBlock (Name "done") [+             Name "r" := Phi {+               type' = i32,+               incomingValues = [(LocalReference i32 (UnName 1), Name "take"),(ConstantOperand (C.Int 32 57), Name "here")],+               metadata = []+              }+            ] (+              Do $ Ret (Just (LocalReference i32 (Name "r"))) []+            )+           ]+         },+        FunctionAttributes (A.GroupID 0) [A.NoUnwind, A.ReadNone, A.UWTable]+       ],++    testCase "BasicBlockVectorization" $ do+      let+        mIn = Module "<string>" "<string>" Nothing Nothing [+          GlobalDefinition $ functionDefaults {+           G.returnType = double,+            G.name = Name "foo",+            G.parameters = ([+              Parameter double (Name (l ++ n)) []+                | l <- [ "a", "b" ], n <- ["1", "2"]+             ], False),+            G.basicBlocks = [+              BasicBlock (UnName 0) ([+                Name (l ++ n) := op NoFastMathFlags (LocalReference double (Name (o1 ++ n))) (LocalReference double (Name (o2 ++ n))) []+                | (l, op, o1, o2) <- [+                   ("x", FSub, "a", "b"),+                   ("y", FMul, "x", "a"),+                   ("z", FAdd, "y", "b")],+                  n <- ["1", "2"]+               ] ++ [+                Name "r" := FMul NoFastMathFlags (LocalReference double (Name "z1")) (LocalReference double (Name "z2")) []+              ]) (Do $ Ret (Just (LocalReference double (Name "r"))) [])+             ]+          }+         ]+      mOut <- optimize (defaultPassSetSpec {+                    transforms = [+                     T.defaultVectorizeBasicBlocks { T.requiredChainDepth = 3 },+                     T.InstructionCombining, +                     T.GlobalValueNumbering False+                    ] }) mIn+      isVectory mOut,+      +    testCase "LoopVectorize" $ do+      let+        mIn = +          Module {+            moduleName = "<string>",+            moduleSourceFileName = "<string>",+            moduleDataLayout = Just $ (defaultDataLayout BigEndian) { +              typeLayouts = Map.singleton (VectorAlign, 128) (AlignmentInfo 128 Nothing)+             },+            moduleTargetTriple = Just "x86_64",+            moduleDefinitions = [+              GlobalDefinition $ globalVariableDefaults {+                G.name = Name "a",+                G.linkage = L.Common,+                G.type' = A.T.ArrayType 2048 i32,+                G.initializer = Just (C.Null (A.T.ArrayType 2048 i32))+               },+              GlobalDefinition $ functionDefaults {+                G.returnType = A.T.void,+                G.name = Name "inc",+                G.functionAttributes = [Left (A.GroupID 0)],+                G.parameters = ([Parameter i32 (Name "n") []], False),+                G.basicBlocks = [+                  BasicBlock (UnName 0) [+                    UnName 1 := ICmp IPred.SGT (LocalReference i32 (Name "n")) (ConstantOperand (C.Int 32 0)) []+                   ] (Do $ CondBr (LocalReference i1 (UnName 1)) (Name ".lr.ph") (Name "._crit_edge") []),+                  BasicBlock (Name ".lr.ph") [+                    Name "indvars.iv" := Phi i64 [ +                      (ConstantOperand (C.Int 64 0), UnName 0),+                      (LocalReference i64 (Name "indvars.iv.next"), Name ".lr.ph")+                     ] [],+                    UnName 2 := GetElementPtr True (ConstantOperand (C.GlobalReference (A.T.ArrayType 2048 i32) (Name "a"))) [ +                      ConstantOperand (C.Int 64 0),+                      (LocalReference i64 (Name "indvars.iv"))+                     ] [],+                    UnName 3 := Load False (LocalReference (ptr i32) (UnName 2)) Nothing 4 [],+                    UnName 4 := Trunc (LocalReference i64 (Name "indvars.iv")) i32 [],+                    UnName 5 := Add True False (LocalReference i32 (UnName 3)) (LocalReference i32 (UnName 4)) [],+                    Do $ Store False (LocalReference (ptr i32) (UnName 2)) (LocalReference i32 (UnName 5)) Nothing 4 [],+                    Name "indvars.iv.next" := Add False False (LocalReference i64 (Name "indvars.iv")) (ConstantOperand (C.Int 64 1)) [],+                    Name "lftr.wideiv" := Trunc (LocalReference i64 (Name "indvars.iv.next")) i32 [],+                    Name "exitcond" := ICmp IPred.EQ (LocalReference i32 (Name "lftr.wideiv")) (LocalReference i32 (Name "n")) []+                   ] (Do $ CondBr (LocalReference i1 (Name "exitcond")) (Name "._crit_edge") (Name ".lr.ph") []),+                  BasicBlock (Name "._crit_edge") [+                   ] (Do $ Ret Nothing [])+                 ]+               },+              FunctionAttributes (A.GroupID 0) [A.NoUnwind, A.ReadNone, A.UWTable, A.StackProtect]+             ]+           }+      mOut <- do+        let triple = "x86_64"+        (target, _) <- failInIO $ lookupTarget Nothing triple+        withTargetOptions $ \targetOptions -> do+          withTargetMachine target triple "" Map.empty targetOptions R.Default CM.Default CGO.Default $ \tm -> do+            optimize (defaultPassSetSpec { +                        transforms = [ T.defaultLoopVectorize ],+                        dataLayout = moduleDataLayout mIn,+                        targetMachine = Just tm+                      }) mIn+      isVectory mOut,++    testCase "LowerInvoke" $ do+      -- This test doesn't test much about what LowerInvoke does, just that it seems to work.+      -- The pass seems to be quite deeply dependent on weakly documented presumptions about+      -- how unwinding works (as is the invoke instruction)+      withContext $ \context -> do+        withPassManager (defaultPassSetSpec { transforms = [T.LowerInvoke] }) $ \passManager -> do+          let astIn = +                Module "<string>" "<string>" Nothing Nothing [+                  GlobalDefinition $ functionDefaults {+                    G.returnType = i32,+                    G.name = Name "foo",+                    G.parameters = ([Parameter i32 (Name "x") []], False),+                    G.basicBlocks = [+                      BasicBlock (Name "here") [+                      ] (+                        Do $ Ret (Just (ConstantOperand (C.Int 32 0))) []+                      )+                     ]+                   }+                 ] +          astOut <- withModuleFromAST' context astIn $ \mIn -> do+            runPassManager passManager mIn+            moduleAST mIn+          astOut @?= Module "<string>" "<string>" Nothing Nothing [+                  GlobalDefinition $ functionDefaults {+                    G.returnType = i32,+                    G.name = Name "foo",+                    G.parameters = ([Parameter i32 (Name "x") []], False),+                    G.basicBlocks = [+                      BasicBlock (Name "here") [+                      ] (+                        Do $ Ret (Just (ConstantOperand (C.Int 32 0))) []+                      )+                    ]+                  }+                 ]+   ]+ ]
+ test/LLVM/Test/OrcJIT.hs view
@@ -0,0 +1,103 @@+{-# LANGUAGE ForeignFunctionInterface #-}+module LLVM.Test.OrcJIT where++import Test.Tasty+import Test.Tasty.HUnit++import LLVM.Test.Support++import Data.Foldable+import Data.IORef+import Data.Word+import Foreign.Ptr++import LLVM.Context+import LLVM.Module+import LLVM.OrcJIT+import LLVM.OrcJIT.IRCompileLayer (IRCompileLayer, withIRCompileLayer)+import qualified LLVM.OrcJIT.IRCompileLayer as IRCompileLayer+import LLVM.OrcJIT.CompileOnDemandLayer (CompileOnDemandLayer, withIndirectStubsManagerBuilder, withJITCompileCallbackManager, withCompileOnDemandLayer)+import qualified LLVM.OrcJIT.CompileOnDemandLayer as CODLayer+import LLVM.Target++testModule :: String+testModule =+  "; ModuleID = '<string>'\n\+  \source_filename = \"<string>\"\n\+  \\n\+  \declare i32 @testFunc()\n\+  \define i32 @main(i32, i8**) {\n\+  \  %3 = call i32 @testFunc()\n\+  \  ret i32 %3\n\+  \}\n"++withTestModule :: (Module -> IO a) -> IO a+withTestModule f = withContext $ \context -> withModuleFromLLVMAssembly' context testModule f++myTestFuncImpl :: IO Word32+myTestFuncImpl = return 42++foreign import ccall "wrapper"+  wrapTestFunc :: IO Word32 -> IO (FunPtr (IO Word32))++foreign import ccall "dynamic"+  mkMain :: FunPtr (IO Word32) -> IO Word32++nullResolver :: MangledSymbol -> IO JITSymbol+nullResolver s = putStrLn "nullresolver" >> return (JITSymbol 0 (JITSymbolFlags False False))++resolver :: MangledSymbol -> IRCompileLayer -> MangledSymbol -> IO JITSymbol+resolver testFunc compileLayer symbol+  | symbol == testFunc = do+      funPtr <- wrapTestFunc myTestFuncImpl+      let addr = ptrToWordPtr (castFunPtrToPtr funPtr)+      return (JITSymbol addr (JITSymbolFlags False True))+  | otherwise = IRCompileLayer.findSymbol compileLayer symbol True++codResolver :: MangledSymbol -> CompileOnDemandLayer -> MangledSymbol -> IO JITSymbol+codResolver testFunc compileLayer symbol+  | symbol == testFunc = do+      funPtr <- wrapTestFunc myTestFuncImpl+      let addr = ptrToWordPtr (castFunPtrToPtr funPtr)+      return (JITSymbol addr (JITSymbolFlags False True))+  | otherwise = CODLayer.findSymbol compileLayer symbol True++tests :: TestTree+tests =+  testGroup "OrcJit" [+    testCase "eager compilation" $ do+      withTestModule $ \mod ->+        failInIO $ withHostTargetMachine $ \tm ->+          withObjectLinkingLayer $ \objectLayer ->+            withIRCompileLayer objectLayer tm $ \compileLayer -> do+              testFunc <- IRCompileLayer.mangleSymbol compileLayer "testFunc"+              IRCompileLayer.withModuleSet+                compileLayer+                [mod]+                (SymbolResolver (resolver testFunc compileLayer) nullResolver) $+                \moduleSet -> do+                  mainSymbol <- IRCompileLayer.mangleSymbol compileLayer "main"+                  JITSymbol mainFn _ <- IRCompileLayer.findSymbol compileLayer mainSymbol True+                  result <- mkMain (castPtrToFunPtr (wordPtrToPtr mainFn))+                  result @?= 42,++    testCase "lazy compilation" $ do+      withTestModule $ \mod ->+        failInIO $ withHostTargetMachine $ \tm -> do+          triple <- getTargetMachineTriple tm+          withObjectLinkingLayer $ \objectLayer ->+            withIRCompileLayer objectLayer tm $ \baseLayer ->+              withIndirectStubsManagerBuilder triple $ \stubsMgr ->+                withJITCompileCallbackManager triple Nothing $ \callbackMgr ->+                  withCompileOnDemandLayer baseLayer (\x -> return [x]) callbackMgr stubsMgr False $ \compileLayer -> do+                    testFunc <- CODLayer.mangleSymbol compileLayer "testFunc"+                    CODLayer.withModuleSet+                      compileLayer+                      [mod]+                      (SymbolResolver (codResolver testFunc compileLayer) nullResolver) $+                      \moduleSet -> do+                        mainSymbol <- CODLayer.mangleSymbol compileLayer "main"+                        JITSymbol mainFn _ <- CODLayer.findSymbol compileLayer mainSymbol True+                        result <- mkMain (castPtrToFunPtr (wordPtrToPtr mainFn))+                        result @?= 42+  ]
+ test/LLVM/Test/Support.hs view
@@ -0,0 +1,42 @@+module LLVM.Test.Support where++import Test.Tasty+import Test.Tasty.HUnit++import Data.Functor+import Control.Monad+import Control.Monad.Trans.Except+import Text.Show.Pretty++import LLVM.Context+import LLVM.Module+import LLVM.Diagnostic++class FailInIO f where+  errorToString :: f -> String++failInIO :: FailInIO f => ExceptT f IO a -> IO a+failInIO = either (fail . errorToString) return <=< runExceptT++instance FailInIO String where+  errorToString = id++instance FailInIO (Either String Diagnostic) where+  errorToString = either id diagnosticDisplay++withModuleFromLLVMAssembly' c s f  = failInIO $ withModuleFromLLVMAssembly c s f+withModuleFromAST' c a f = failInIO $ withModuleFromAST c a f+withModuleFromBitcode' c a f = failInIO $ withModuleFromBitcode c ("<string>", a) f++assertEqPretty :: (Eq a, Show a) => a -> a -> Assertion+assertEqPretty actual expected = do+  assertBool+   ("expected: " ++ ppShow expected ++ "\n" ++ "but got: " ++ ppShow actual ++ "\n")+   (expected == actual)++strCheckC mAST mStr mStrCanon = withContext $ \context -> do+  a <- withModuleFromLLVMAssembly' context mStr moduleAST+  s <- withModuleFromAST' context mAST moduleLLVMAssembly+  (a,s) `assertEqPretty` (mAST, mStrCanon)++strCheck mAST mStr = strCheckC mAST mStr mStr
+ test/LLVM/Test/Target.hs view
@@ -0,0 +1,71 @@+{-# LANGUAGE+  RecordWildCards+  #-}+module LLVM.Test.Target where++import Test.Tasty+import Test.Tasty.HUnit+import Test.Tasty.QuickCheck+import Test.QuickCheck+import Test.QuickCheck.Property++import Control.Monad++import LLVM.Target+import LLVM.Target.Options+import LLVM.Target.LibraryFunction++instance Arbitrary FloatABI where+  arbitrary = elements [minBound .. maxBound]++instance Arbitrary FloatingPointOperationFusionMode where+  arbitrary = elements [minBound .. maxBound]++instance Arbitrary Options where+  arbitrary = do+    printMachineCode <- arbitrary+    lessPreciseFloatingPointMultiplyAddOption <- arbitrary+    unsafeFloatingPointMath <- arbitrary+    noInfinitiesFloatingPointMath <- arbitrary+    noNaNsFloatingPointMath <- arbitrary+    honorSignDependentRoundingFloatingPointMathOption <- arbitrary+    noZerosInBSS <- arbitrary+    guaranteedTailCallOptimization <- arbitrary+    enableFastInstructionSelection <- arbitrary+    useInitArray <- arbitrary+    disableIntegratedAssembler <- arbitrary+    compressDebugSections <- arbitrary+    trapUnreachable <- arbitrary+    stackAlignmentOverride <- arbitrary+    floatABIType <- arbitrary+    allowFloatingPointOperationFusion <- arbitrary+    return Options { .. }++tests = testGroup "Target" [+  testGroup "Options" [+     testProperty "basic" $ \options -> ioProperty $ do+       withTargetOptions $ \to -> do+         pokeTargetOptions options to+         options' <- peekTargetOptions to+         return $ options == options'+   ],+  testGroup "LibraryFunction" [+    testGroup "set-get" [+       testCase (show lf) $ do+         triple <- getDefaultTargetTriple+         withTargetLibraryInfo triple $ \tli -> do+           setLibraryFunctionAvailableWithName tli lf "foo"+           nm <- getLibraryFunctionName tli lf+           nm @?= "foo"+       | lf <- [minBound, maxBound]+     ],+    testCase "get" $ do+      triple <- getDefaultTargetTriple+      withTargetLibraryInfo triple $ \tli -> do+        lf <- getLibraryFunction tli "printf"+        lf @?= Just LF__printf+   ],+  testCase "Host" $ do+    features <- getHostCPUFeatures+    return ()+ ]
+ test/LLVM/Test/Tests.hs view
@@ -0,0 +1,39 @@+module LLVM.Test.Tests where++import Test.Tasty++import qualified LLVM.Test.Analysis as Analysis+import qualified LLVM.Test.CallingConvention as CallingConvention+import qualified LLVM.Test.Constants as Constants+import qualified LLVM.Test.DataLayout as DataLayout+import qualified LLVM.Test.ExecutionEngine as ExecutionEngine+import qualified LLVM.Test.Global as Global+import qualified LLVM.Test.InlineAssembly as InlineAssembly+import qualified LLVM.Test.Instructions as Instructions+import qualified LLVM.Test.Instrumentation as Instrumentation+import qualified LLVM.Test.Linking as Linking+import qualified LLVM.Test.Metadata as Metadata+import qualified LLVM.Test.Module as Module+import qualified LLVM.Test.ObjectCode as ObjectCode+import qualified LLVM.Test.Optimization as Optimization+import qualified LLVM.Test.OrcJIT as OrcJIT+import qualified LLVM.Test.Target as Target++tests = testGroup "llvm-hs" [+    CallingConvention.tests,+    Constants.tests,+    DataLayout.tests,+    ExecutionEngine.tests,+    Global.tests,+    InlineAssembly.tests,+    Instructions.tests,+    Metadata.tests,+    Module.tests,+    OrcJIT.tests,+    Optimization.tests,+    Target.tests,+    Analysis.tests,+    Linking.tests,+    Instrumentation.tests,+    ObjectCode.tests+  ]
+ test/Test.hs view
@@ -0,0 +1,10 @@+import Test.Tasty+import qualified LLVM.Test.Tests as LLVM+import LLVM.CommandLine++main = do+  parseCommandLineOptions [+    "test",+    "-bb-vectorize-ignore-target-info"+   ] Nothing+  defaultMain LLVM.tests