{-# LANGUAGE
  TemplateHaskell,
  MultiParamTypeClasses,
  RecordWildCards,
  UndecidableInstances,
  OverloadedStrings
  #-}
module LLVM.Internal.Target where

import LLVM.Prelude

import Control.Monad.AnyCont
import Control.Monad.Catch
import Control.Monad.Fail (MonadFail)
import Control.Monad.IO.Class
import Control.Monad.Trans.Except

import Data.Attoparsec.ByteString
import Data.Attoparsec.ByteString.Char8
import qualified Data.ByteString as ByteString
import Data.Char
import Data.Map (Map)
import qualified Data.Map as Map
import Foreign.C.String
import Foreign.Ptr

import LLVM.Internal.Coding
import LLVM.Internal.String ()
import LLVM.Internal.LibraryFunction
import LLVM.DataLayout
import LLVM.Exception

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)
 ]

genCodingInstance[t| TO.DebugCompressionType |] ''FFI.DebugCompressionType [
  (FFI.debugCompressionTypeNone, TO.CompressNone),
  (FFI.debugCompressionTypeGNU, TO.CompressGNU),
  (FFI.debugCompressionTypeZ, TO.CompressZ)
  ]

genCodingInstance[t| TO.ThreadModel |] ''FFI.ThreadModel [
  (FFI.threadModelPOSIX, TO.ThreadModelPOSIX),
  (FFI.threadModelSingle, TO.ThreadModelSingle)
 ]

genCodingInstance[t| TO.EABIVersion |] ''FFI.EABI [
  (FFI.eabiVersionUnknown, TO.EABIVersionUnknown),
  (FFI.eabiVersionDefault, TO.EABIVersionDefault),
  (FFI.eabiVersionEABI4, TO.EABIVersion4),
  (FFI.eabiVersionEABI5, TO.EABIVersion5),
  (FFI.eabiVersionGNU, TO.EABIVersionGNU)
 ]

genCodingInstance[t| TO.DebuggerKind |] ''FFI.DebuggerKind [
  (FFI.debuggerKindDefault, TO.DebuggerDefault),
  (FFI.debuggerKindGDB, TO.DebuggerGDB),
  (FFI.debuggerKindLLDB, TO.DebuggerLLDB),
  (FFI.debuggerKindSCE, TO.DebuggerSCE)
 ]

genCodingInstance[t| TO.FloatingPointDenormalMode |] ''FFI.FPDenormalMode [
  (FFI.fpDenormalModeIEEE, TO.FloatingPointDenormalIEEE),
  (FFI.fpDenormalModePreserveSign, TO.FloatingPointDenormalPreserveSign),
  (FFI.fpDenormalModePositiveZero, TO.FloatingPointDenormalPositiveZero)
 ]

genCodingInstance[t| TO.ExceptionHandling |] ''FFI.ExceptionHandling [
  (FFI.exceptionHandlingNone, TO.ExceptionHandlingNone),
  (FFI.exceptionHandlingDwarfCFI, TO.ExceptionHandlingDwarfCFI),
  (FFI.exceptionHandlingSjLj, TO.ExceptionHandlingSjLj),
  (FFI.exceptionHandlingARM, TO.ExceptionHandlingARM),
  (FFI.exceptionHandlingWinEH, TO.ExceptionHandlingWinEH)
 ]

-- | <http://llvm.org/doxygen/classllvm_1_1Target.html>
newtype Target = Target (Ptr FFI.Target)

-- | e.g. an instruction set extension
newtype CPUFeature = CPUFeature ByteString
  deriving (CPUFeature -> CPUFeature -> Bool
(CPUFeature -> CPUFeature -> Bool)
-> (CPUFeature -> CPUFeature -> Bool) -> Eq CPUFeature
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CPUFeature -> CPUFeature -> Bool
$c/= :: CPUFeature -> CPUFeature -> Bool
== :: CPUFeature -> CPUFeature -> Bool
$c== :: CPUFeature -> CPUFeature -> Bool
Eq, Eq CPUFeature
Eq CPUFeature =>
(CPUFeature -> CPUFeature -> Ordering)
-> (CPUFeature -> CPUFeature -> Bool)
-> (CPUFeature -> CPUFeature -> Bool)
-> (CPUFeature -> CPUFeature -> Bool)
-> (CPUFeature -> CPUFeature -> Bool)
-> (CPUFeature -> CPUFeature -> CPUFeature)
-> (CPUFeature -> CPUFeature -> CPUFeature)
-> Ord CPUFeature
CPUFeature -> CPUFeature -> Bool
CPUFeature -> CPUFeature -> Ordering
CPUFeature -> CPUFeature -> CPUFeature
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: CPUFeature -> CPUFeature -> CPUFeature
$cmin :: CPUFeature -> CPUFeature -> CPUFeature
max :: CPUFeature -> CPUFeature -> CPUFeature
$cmax :: CPUFeature -> CPUFeature -> CPUFeature
>= :: CPUFeature -> CPUFeature -> Bool
$c>= :: CPUFeature -> CPUFeature -> Bool
> :: CPUFeature -> CPUFeature -> Bool
$c> :: CPUFeature -> CPUFeature -> Bool
<= :: CPUFeature -> CPUFeature -> Bool
$c<= :: CPUFeature -> CPUFeature -> Bool
< :: CPUFeature -> CPUFeature -> Bool
$c< :: CPUFeature -> CPUFeature -> Bool
compare :: CPUFeature -> CPUFeature -> Ordering
$ccompare :: CPUFeature -> CPUFeature -> Ordering
$cp1Ord :: Eq CPUFeature
Ord, ReadPrec [CPUFeature]
ReadPrec CPUFeature
Int -> ReadS CPUFeature
ReadS [CPUFeature]
(Int -> ReadS CPUFeature)
-> ReadS [CPUFeature]
-> ReadPrec CPUFeature
-> ReadPrec [CPUFeature]
-> Read CPUFeature
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [CPUFeature]
$creadListPrec :: ReadPrec [CPUFeature]
readPrec :: ReadPrec CPUFeature
$creadPrec :: ReadPrec CPUFeature
readList :: ReadS [CPUFeature]
$creadList :: ReadS [CPUFeature]
readsPrec :: Int -> ReadS CPUFeature
$creadsPrec :: Int -> ReadS CPUFeature
Read, Int -> CPUFeature -> ShowS
[CPUFeature] -> ShowS
CPUFeature -> String
(Int -> CPUFeature -> ShowS)
-> (CPUFeature -> String)
-> ([CPUFeature] -> ShowS)
-> Show CPUFeature
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CPUFeature] -> ShowS
$cshowList :: [CPUFeature] -> ShowS
show :: CPUFeature -> String
$cshow :: CPUFeature -> String
showsPrec :: Int -> CPUFeature -> ShowS
$cshowsPrec :: Int -> CPUFeature -> ShowS
Show)

instance EncodeM e ByteString es => EncodeM e (Map CPUFeature Bool) es where
  encodeM :: Map CPUFeature Bool -> e es
encodeM = ByteString -> e es
forall (e :: * -> *) h c. EncodeM e h c => h -> e c
encodeM (ByteString -> e es)
-> (Map CPUFeature Bool -> ByteString)
-> Map CPUFeature Bool
-> e es
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> [ByteString] -> ByteString
ByteString.intercalate "," ([ByteString] -> ByteString)
-> (Map CPUFeature Bool -> [ByteString])
-> Map CPUFeature Bool
-> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((CPUFeature, Bool) -> ByteString)
-> [(CPUFeature, Bool)] -> [ByteString]
forall a b. (a -> b) -> [a] -> [b]
map (\(CPUFeature f :: ByteString
f, enabled :: Bool
enabled) -> (if Bool
enabled then "+" else "-") ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
f) ([(CPUFeature, Bool)] -> [ByteString])
-> (Map CPUFeature Bool -> [(CPUFeature, Bool)])
-> Map CPUFeature Bool
-> [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map CPUFeature Bool -> [(CPUFeature, Bool)]
forall k a. Map k a -> [(k, a)]
Map.toList

instance (MonadFail d, DecodeM d ByteString es) => DecodeM d (Map CPUFeature Bool) es where
  decodeM :: es -> d (Map CPUFeature Bool)
decodeM es :: es
es = do
    ByteString
s <- es -> d ByteString
forall (d :: * -> *) h c. DecodeM d h c => c -> d h
decodeM es
es
    let flag :: Parser ByteString (CPUFeature, Bool)
flag = do
          Bool
en <- [Parser ByteString Bool] -> Parser ByteString Bool
forall (f :: * -> *) a. Alternative f => [f a] -> f a
choice [Char -> Parser Word8
char8 '-' Parser Word8 -> Parser ByteString Bool -> Parser ByteString Bool
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Bool -> Parser ByteString Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False, Char -> Parser Word8
char8 '+' Parser Word8 -> Parser ByteString Bool -> Parser ByteString Bool
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Bool -> Parser ByteString Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True]
          ByteString
s <- [Word8] -> ByteString
ByteString.pack ([Word8] -> ByteString)
-> Parser ByteString [Word8] -> Parser ByteString ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Word8 -> Parser ByteString [Word8]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many1 (Word8 -> Parser Word8
notWord8 (Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Char -> Int
ord ',')))
          (CPUFeature, Bool) -> Parser ByteString (CPUFeature, Bool)
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString -> CPUFeature
CPUFeature ByteString
s, Bool
en)
        features :: Parser ByteString (Map CPUFeature Bool)
features = ([(CPUFeature, Bool)] -> Map CPUFeature Bool)
-> Parser ByteString [(CPUFeature, Bool)]
-> Parser ByteString (Map CPUFeature Bool)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM [(CPUFeature, Bool)] -> Map CPUFeature Bool
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList (Parser ByteString (CPUFeature, Bool)
flag Parser ByteString (CPUFeature, Bool)
-> Parser Word8 -> Parser ByteString [(CPUFeature, Bool)]
forall (f :: * -> *) a s. Alternative f => f a -> f s -> f [a]
`sepBy` (Char -> Parser Word8
char8 ','))
    case Parser ByteString (Map CPUFeature Bool)
-> ByteString -> Either String (Map CPUFeature Bool)
forall a. Parser a -> ByteString -> Either String a
parseOnly (Parser ByteString (Map CPUFeature Bool)
features Parser ByteString (Map CPUFeature Bool)
-> Parser ByteString () -> Parser ByteString (Map CPUFeature Bool)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ByteString ()
forall t. Chunk t => Parser t ()
endOfInput) ByteString
s of
      Right features :: Map CPUFeature Bool
features -> Map CPUFeature Bool -> d (Map CPUFeature Bool)
forall (m :: * -> *) a. Monad m => a -> m a
return Map CPUFeature Bool
features
      Left err :: String
err -> String -> d (Map CPUFeature Bool)
forall (m :: * -> *) a. MonadFail m => String -> m a
fail ("failure to parse CPUFeature string: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
err)
                       
-- | 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. May throw
-- 'LookupTargetException' if no target is found.
lookupTarget ::
  Maybe ShortByteString -- ^ arch
  -> ShortByteString -- ^ \"triple\" - e.g. x86_64-unknown-linux-gnu
  -> IO (Target, ShortByteString)
lookupTarget :: Maybe ShortByteString
-> ShortByteString -> IO (Target, ShortByteString)
lookupTarget arch :: Maybe ShortByteString
arch triple :: ShortByteString
triple = (AnyContT IO (Target, ShortByteString)
 -> ((Target, ShortByteString) -> IO (Target, ShortByteString))
 -> IO (Target, ShortByteString))
-> ((Target, ShortByteString) -> IO (Target, ShortByteString))
-> AnyContT IO (Target, ShortByteString)
-> IO (Target, ShortByteString)
forall a b c. (a -> b -> c) -> b -> a -> c
flip AnyContT IO (Target, ShortByteString)
-> ((Target, ShortByteString) -> IO (Target, ShortByteString))
-> IO (Target, ShortByteString)
forall (m :: * -> *) a. AnyContT m a -> forall r. (a -> m r) -> m r
runAnyContT (Target, ShortByteString) -> IO (Target, ShortByteString)
forall (m :: * -> *) a. Monad m => a -> m a
return (AnyContT IO (Target, ShortByteString)
 -> IO (Target, ShortByteString))
-> AnyContT IO (Target, ShortByteString)
-> IO (Target, ShortByteString)
forall a b. (a -> b) -> a -> b
$ do
  Ptr (OwnerTransfered CString)
cErrorP <- AnyContT IO (Ptr (OwnerTransfered CString))
forall a (m :: * -> *).
(Storable a, MonadAnyCont IO m) =>
m (Ptr a)
alloca
  Ptr (OwnerTransfered CString)
cNewTripleP <- AnyContT IO (Ptr (OwnerTransfered CString))
forall a (m :: * -> *).
(Storable a, MonadAnyCont IO m) =>
m (Ptr a)
alloca
  CString
arch <- ShortByteString -> AnyContT IO CString
forall (e :: * -> *) h c. EncodeM e h c => h -> e c
encodeM (ShortByteString
-> (ShortByteString -> ShortByteString)
-> Maybe ShortByteString
-> ShortByteString
forall b a. b -> (a -> b) -> Maybe a -> b
maybe "" ShortByteString -> ShortByteString
forall a. a -> a
id Maybe ShortByteString
arch)
  CString
triple <- ShortByteString -> AnyContT IO CString
forall (e :: * -> *) h c. EncodeM e h c => h -> e c
encodeM ShortByteString
triple
  Ptr Target
target <- IO (Ptr Target) -> AnyContT IO (Ptr Target)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Ptr Target) -> AnyContT IO (Ptr Target))
-> IO (Ptr Target) -> AnyContT IO (Ptr Target)
forall a b. (a -> b) -> a -> b
$ CString
-> CString
-> Ptr (OwnerTransfered CString)
-> Ptr (OwnerTransfered CString)
-> IO (Ptr Target)
FFI.lookupTarget CString
arch CString
triple Ptr (OwnerTransfered CString)
cNewTripleP Ptr (OwnerTransfered CString)
cErrorP
  Bool -> AnyContT IO () -> AnyContT IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Ptr Target
target Ptr Target -> Ptr Target -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr Target
forall a. Ptr a
nullPtr) (AnyContT IO () -> AnyContT IO ())
-> AnyContT IO () -> AnyContT IO ()
forall a b. (a -> b) -> a -> b
$ LookupTargetException -> AnyContT IO ()
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (LookupTargetException -> AnyContT IO ())
-> (String -> LookupTargetException) -> String -> AnyContT IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> LookupTargetException
LookupTargetException (String -> AnyContT IO ()) -> AnyContT IO String -> AnyContT IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr (OwnerTransfered CString) -> AnyContT IO String
forall (d :: * -> *) h c. DecodeM d h c => c -> d h
decodeM Ptr (OwnerTransfered CString)
cErrorP
  (ShortByteString -> (Target, ShortByteString))
-> AnyContT IO ShortByteString
-> AnyContT IO (Target, ShortByteString)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (Ptr Target -> Target
Target Ptr Target
target, ) (AnyContT IO ShortByteString
 -> AnyContT IO (Target, ShortByteString))
-> AnyContT IO ShortByteString
-> AnyContT IO (Target, ShortByteString)
forall a b. (a -> b) -> a -> b
$ Ptr (OwnerTransfered CString) -> AnyContT IO ShortByteString
forall (d :: * -> *) h c. DecodeM d h c => c -> d h
decodeM Ptr (OwnerTransfered CString)
cNewTripleP

-- | <http://llvm.org/doxygen/classllvm_1_1TargetOptions.html>
newtype TargetOptions = TargetOptions (Ptr FFI.TargetOptions)

newtype MCTargetOptions = MCTargetOptions (Ptr FFI.MCTargetOptions)

-- | bracket creation and destruction of a 'TargetOptions' object
withTargetOptions :: (TargetOptions -> IO a) -> IO a
withTargetOptions :: (TargetOptions -> IO a) -> IO a
withTargetOptions = IO (Ptr TargetOptions)
-> (Ptr TargetOptions -> IO ())
-> (Ptr TargetOptions -> IO a)
-> IO a
forall (m :: * -> *) a c b.
MonadMask m =>
m a -> (a -> m c) -> (a -> m b) -> m b
bracket IO (Ptr TargetOptions)
FFI.createTargetOptions Ptr TargetOptions -> IO ()
FFI.disposeTargetOptions ((Ptr TargetOptions -> IO a) -> IO a)
-> ((TargetOptions -> IO a) -> Ptr TargetOptions -> IO a)
-> (TargetOptions -> IO a)
-> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((TargetOptions -> IO a)
-> (Ptr TargetOptions -> TargetOptions)
-> Ptr TargetOptions
-> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr TargetOptions -> TargetOptions
TargetOptions)

-- | set all target options
pokeTargetOptions :: TO.Options -> TargetOptions -> IO ()
pokeTargetOptions :: Options -> TargetOptions -> IO ()
pokeTargetOptions hOpts :: Options
hOpts opts :: TargetOptions
opts@(TargetOptions cOpts :: Ptr TargetOptions
cOpts) = do
  ((TargetOptionFlag, Options -> Bool) -> IO ())
-> [(TargetOptionFlag, Options -> Bool)] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (\(c :: TargetOptionFlag
c, ha :: Options -> Bool
ha) -> Ptr TargetOptions -> TargetOptionFlag -> LLVMBool -> IO ()
FFI.setTargetOptionFlag Ptr TargetOptions
cOpts TargetOptionFlag
c (LLVMBool -> IO ()) -> IO LLVMBool -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Bool -> IO LLVMBool
forall (e :: * -> *) h c. EncodeM e h c => h -> e c
encodeM (Options -> Bool
ha Options
hOpts)) [
    (TargetOptionFlag
FFI.targetOptionFlagPrintMachineCode, Options -> Bool
TO.printMachineCode),
    (TargetOptionFlag
FFI.targetOptionFlagUnsafeFPMath, Options -> Bool
TO.unsafeFloatingPointMath),
    (TargetOptionFlag
FFI.targetOptionFlagNoInfsFPMath, Options -> Bool
TO.noInfinitiesFloatingPointMath),
    (TargetOptionFlag
FFI.targetOptionFlagNoNaNsFPMath, Options -> Bool
TO.noNaNsFloatingPointMath),
    (TargetOptionFlag
FFI.targetOptionFlagNoTrappingFPMath, Options -> Bool
TO.noTrappingFloatingPointMath),
    (TargetOptionFlag
FFI.targetOptionFlagNoSignedZerosFPMath, Options -> Bool
TO.noSignedZeroesFloatingPointMath),
    (TargetOptionFlag
FFI.targetOptionFlagHonorSignDependentRoundingFPMathOption, Options -> Bool
TO.honorSignDependentRoundingFloatingPointMathOption),
    (TargetOptionFlag
FFI.targetOptionFlagNoZerosInBSS, Options -> Bool
TO.noZerosInBSS),
    (TargetOptionFlag
FFI.targetOptionFlagGuaranteedTailCallOpt, Options -> Bool
TO.guaranteedTailCallOptimization),
    (TargetOptionFlag
FFI.targetOptionFlagStackSymbolOrdering, Options -> Bool
TO.stackSymbolOrdering),
    (TargetOptionFlag
FFI.targetOptionFlagEnableFastISel, Options -> Bool
TO.enableFastInstructionSelection),
    (TargetOptionFlag
FFI.targetOptionFlagUseInitArray, Options -> Bool
TO.useInitArray),
    (TargetOptionFlag
FFI.targetOptionFlagDisableIntegratedAS, Options -> Bool
TO.disableIntegratedAssembler),
    (TargetOptionFlag
FFI.targetOptionFlagRelaxELFRelocations, Options -> Bool
TO.relaxELFRelocations),
    (TargetOptionFlag
FFI.targetOptionFlagFunctionSections, Options -> Bool
TO.functionSections),
    (TargetOptionFlag
FFI.targetOptionFlagDataSections, Options -> Bool
TO.dataSections),
    (TargetOptionFlag
FFI.targetOptionFlagUniqueSectionNames, Options -> Bool
TO.uniqueSectionNames),
    (TargetOptionFlag
FFI.targetOptionFlagTrapUnreachable, Options -> Bool
TO.trapUnreachable),
    (TargetOptionFlag
FFI.targetOptionFlagEmulatedTLS, Options -> Bool
TO.emulatedThreadLocalStorage),
    (TargetOptionFlag
FFI.targetOptionFlagEnableIPRA, Options -> Bool
TO.enableInterProceduralRegisterAllocation)
   ]
  Ptr TargetOptions -> CUInt -> IO ()
FFI.setStackAlignmentOverride Ptr TargetOptions
cOpts (CUInt -> IO ()) -> IO CUInt -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Word32 -> IO CUInt
forall (e :: * -> *) h c. EncodeM e h c => h -> e c
encodeM (Options -> Word32
TO.stackAlignmentOverride Options
hOpts)
  Ptr TargetOptions -> FloatABIType -> IO ()
FFI.setFloatABIType Ptr TargetOptions
cOpts (FloatABIType -> IO ()) -> IO FloatABIType -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< FloatABI -> IO FloatABIType
forall (e :: * -> *) h c. EncodeM e h c => h -> e c
encodeM (Options -> FloatABI
TO.floatABIType Options
hOpts)
  Ptr TargetOptions -> FPOpFusionMode -> IO ()
FFI.setAllowFPOpFusion Ptr TargetOptions
cOpts (FPOpFusionMode -> IO ()) -> IO FPOpFusionMode -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< FloatingPointOperationFusionMode -> IO FPOpFusionMode
forall (e :: * -> *) h c. EncodeM e h c => h -> e c
encodeM (Options -> FloatingPointOperationFusionMode
TO.allowFloatingPointOperationFusion Options
hOpts)
  Ptr TargetOptions -> DebugCompressionType -> IO ()
FFI.setCompressDebugSections Ptr TargetOptions
cOpts (DebugCompressionType -> IO ()) -> IO DebugCompressionType -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< DebugCompressionType -> IO DebugCompressionType
forall (e :: * -> *) h c. EncodeM e h c => h -> e c
encodeM (Options -> DebugCompressionType
TO.compressDebugSections Options
hOpts)
  Ptr TargetOptions -> ThreadModel -> IO ()
FFI.setThreadModel Ptr TargetOptions
cOpts (ThreadModel -> IO ()) -> IO ThreadModel -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ThreadModel -> IO ThreadModel
forall (e :: * -> *) h c. EncodeM e h c => h -> e c
encodeM (Options -> ThreadModel
TO.threadModel Options
hOpts)
  Ptr TargetOptions -> EABI -> IO ()
FFI.setEABIVersion Ptr TargetOptions
cOpts (EABI -> IO ()) -> IO EABI -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< EABIVersion -> IO EABI
forall (e :: * -> *) h c. EncodeM e h c => h -> e c
encodeM (Options -> EABIVersion
TO.eabiVersion Options
hOpts)
  Ptr TargetOptions -> DebuggerKind -> IO ()
FFI.setDebuggerTuning Ptr TargetOptions
cOpts (DebuggerKind -> IO ()) -> IO DebuggerKind -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< DebuggerKind -> IO DebuggerKind
forall (e :: * -> *) h c. EncodeM e h c => h -> e c
encodeM (Options -> DebuggerKind
TO.debuggerTuning Options
hOpts)
  Ptr TargetOptions -> FPDenormalMode -> IO ()
FFI.setFPDenormalMode Ptr TargetOptions
cOpts (FPDenormalMode -> IO ()) -> IO FPDenormalMode -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< FloatingPointDenormalMode -> IO FPDenormalMode
forall (e :: * -> *) h c. EncodeM e h c => h -> e c
encodeM (Options -> FloatingPointDenormalMode
TO.floatingPointDenormalMode Options
hOpts)
  Ptr TargetOptions -> ExceptionHandling -> IO ()
FFI.setExceptionModel Ptr TargetOptions
cOpts (ExceptionHandling -> IO ()) -> IO ExceptionHandling -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ExceptionHandling -> IO ExceptionHandling
forall (e :: * -> *) h c. EncodeM e h c => h -> e c
encodeM (Options -> ExceptionHandling
TO.exceptionModel Options
hOpts)
  MachineCodeOptions -> MCTargetOptions -> IO ()
pokeMachineCodeOptions (Options -> MachineCodeOptions
TO.machineCodeOptions Options
hOpts) (MCTargetOptions -> IO ()) -> IO MCTargetOptions -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< TargetOptions -> IO MCTargetOptions
machineCodeOptions TargetOptions
opts

pokeMachineCodeOptions :: TO.MachineCodeOptions -> MCTargetOptions -> IO ()
pokeMachineCodeOptions :: MachineCodeOptions -> MCTargetOptions -> IO ()
pokeMachineCodeOptions hOpts :: MachineCodeOptions
hOpts (MCTargetOptions cOpts :: Ptr MCTargetOptions
cOpts) =
  ((MCTargetOptionFlag, MachineCodeOptions -> Bool) -> IO ())
-> [(MCTargetOptionFlag, MachineCodeOptions -> Bool)] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (\(c :: MCTargetOptionFlag
c, ha :: MachineCodeOptions -> Bool
ha) -> Ptr MCTargetOptions -> MCTargetOptionFlag -> LLVMBool -> IO ()
FFI.setMCTargetOptionFlag Ptr MCTargetOptions
cOpts MCTargetOptionFlag
c (LLVMBool -> IO ()) -> IO LLVMBool -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Bool -> IO LLVMBool
forall (e :: * -> *) h c. EncodeM e h c => h -> e c
encodeM (MachineCodeOptions -> Bool
ha MachineCodeOptions
hOpts)) [
    (MCTargetOptionFlag
FFI.mcTargetOptionFlagMCRelaxAll, MachineCodeOptions -> Bool
TO.relaxAll),
    (MCTargetOptionFlag
FFI.mcTargetOptionFlagMCNoExecStack, MachineCodeOptions -> Bool
TO.noExecutableStack),
    (MCTargetOptionFlag
FFI.mcTargetOptionFlagMCFatalWarnings, MachineCodeOptions -> Bool
TO.fatalWarnings),
    (MCTargetOptionFlag
FFI.mcTargetOptionFlagMCNoWarn, MachineCodeOptions -> Bool
TO.noWarnings),
    (MCTargetOptionFlag
FFI.mcTargetOptionFlagMCNoDeprecatedWarn, MachineCodeOptions -> Bool
TO.noDeprecatedWarning),
    (MCTargetOptionFlag
FFI.mcTargetOptionFlagMCSaveTempLabels, MachineCodeOptions -> Bool
TO.saveTemporaryLabels),
    (MCTargetOptionFlag
FFI.mcTargetOptionFlagMCUseDwarfDirectory, MachineCodeOptions -> Bool
TO.useDwarfDirectory),
    (MCTargetOptionFlag
FFI.mcTargetOptionFlagMCIncrementalLinkerCompatible, MachineCodeOptions -> Bool
TO.incrementalLinkerCompatible),
    (MCTargetOptionFlag
FFI.mcTargetOptionFlagMCPIECopyRelocations, MachineCodeOptions -> Bool
TO.pieCopyRelocations),
    (MCTargetOptionFlag
FFI.mcTargetOptionFlagShowMCEncoding, MachineCodeOptions -> Bool
TO.showMachineCodeEncoding),
    (MCTargetOptionFlag
FFI.mcTargetOptionFlagShowMCInst, MachineCodeOptions -> Bool
TO.showMachineCodeInstructions),
    (MCTargetOptionFlag
FFI.mcTargetOptionFlagAsmVerbose, MachineCodeOptions -> Bool
TO.verboseAssembly),
    (MCTargetOptionFlag
FFI.mcTargetOptionFlagPreserveAsmComments, MachineCodeOptions -> Bool
TO.preserveComentsInAssembly)
   ]

-- | get all target options
peekTargetOptions :: TargetOptions -> IO TO.Options
peekTargetOptions :: TargetOptions -> IO Options
peekTargetOptions opts :: TargetOptions
opts@(TargetOptions tOpts :: Ptr TargetOptions
tOpts) = do
  let gof :: TargetOptionFlag -> IO Bool
gof = LLVMBool -> IO Bool
forall (d :: * -> *) h c. DecodeM d h c => c -> d h
decodeM (LLVMBool -> IO Bool)
-> (TargetOptionFlag -> IO LLVMBool) -> TargetOptionFlag -> IO Bool
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Ptr TargetOptions -> TargetOptionFlag -> IO LLVMBool
FFI.getTargetOptionsFlag Ptr TargetOptions
tOpts
  Bool
printMachineCode
    <- TargetOptionFlag -> IO Bool
gof TargetOptionFlag
FFI.targetOptionFlagPrintMachineCode
  Bool
unsafeFloatingPointMath
    <- TargetOptionFlag -> IO Bool
gof TargetOptionFlag
FFI.targetOptionFlagUnsafeFPMath
  Bool
noInfinitiesFloatingPointMath
    <- TargetOptionFlag -> IO Bool
gof TargetOptionFlag
FFI.targetOptionFlagNoInfsFPMath
  Bool
noNaNsFloatingPointMath
    <- TargetOptionFlag -> IO Bool
gof TargetOptionFlag
FFI.targetOptionFlagNoNaNsFPMath
  Bool
noTrappingFloatingPointMath
    <- TargetOptionFlag -> IO Bool
gof TargetOptionFlag
FFI.targetOptionFlagNoTrappingFPMath
  Bool
noSignedZeroesFloatingPointMath
    <- TargetOptionFlag -> IO Bool
gof TargetOptionFlag
FFI.targetOptionFlagNoSignedZerosFPMath
  Bool
honorSignDependentRoundingFloatingPointMathOption
    <- TargetOptionFlag -> IO Bool
gof TargetOptionFlag
FFI.targetOptionFlagHonorSignDependentRoundingFPMathOption
  Bool
noZerosInBSS
    <- TargetOptionFlag -> IO Bool
gof TargetOptionFlag
FFI.targetOptionFlagNoZerosInBSS
  Bool
guaranteedTailCallOptimization
    <- TargetOptionFlag -> IO Bool
gof TargetOptionFlag
FFI.targetOptionFlagGuaranteedTailCallOpt
  Bool
stackSymbolOrdering
    <- TargetOptionFlag -> IO Bool
gof TargetOptionFlag
FFI.targetOptionFlagStackSymbolOrdering
  Bool
enableFastInstructionSelection
    <- TargetOptionFlag -> IO Bool
gof TargetOptionFlag
FFI.targetOptionFlagEnableFastISel
  Bool
useInitArray
    <- TargetOptionFlag -> IO Bool
gof TargetOptionFlag
FFI.targetOptionFlagUseInitArray
  Bool
disableIntegratedAssembler
    <- TargetOptionFlag -> IO Bool
gof TargetOptionFlag
FFI.targetOptionFlagDisableIntegratedAS
  DebugCompressionType
compressDebugSections <- DebugCompressionType -> IO DebugCompressionType
forall (d :: * -> *) h c. DecodeM d h c => c -> d h
decodeM (DebugCompressionType -> IO DebugCompressionType)
-> IO DebugCompressionType -> IO DebugCompressionType
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr TargetOptions -> IO DebugCompressionType
FFI.getCompressDebugSections Ptr TargetOptions
tOpts
  Bool
relaxELFRelocations
    <- TargetOptionFlag -> IO Bool
gof TargetOptionFlag
FFI.targetOptionFlagRelaxELFRelocations
  Bool
functionSections
    <- TargetOptionFlag -> IO Bool
gof TargetOptionFlag
FFI.targetOptionFlagFunctionSections
  Bool
dataSections
    <- TargetOptionFlag -> IO Bool
gof TargetOptionFlag
FFI.targetOptionFlagDataSections
  Bool
uniqueSectionNames
    <- TargetOptionFlag -> IO Bool
gof TargetOptionFlag
FFI.targetOptionFlagUniqueSectionNames
  Bool
trapUnreachable
    <- TargetOptionFlag -> IO Bool
gof TargetOptionFlag
FFI.targetOptionFlagTrapUnreachable
  Bool
emulatedThreadLocalStorage
    <- TargetOptionFlag -> IO Bool
gof TargetOptionFlag
FFI.targetOptionFlagEmulatedTLS
  Bool
enableInterProceduralRegisterAllocation
    <- TargetOptionFlag -> IO Bool
gof TargetOptionFlag
FFI.targetOptionFlagEnableIPRA
  Word32
stackAlignmentOverride <- CUInt -> IO Word32
forall (d :: * -> *) h c. DecodeM d h c => c -> d h
decodeM (CUInt -> IO Word32) -> IO CUInt -> IO Word32
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr TargetOptions -> IO CUInt
FFI.getStackAlignmentOverride Ptr TargetOptions
tOpts
  FloatABI
floatABIType <- FloatABIType -> IO FloatABI
forall (d :: * -> *) h c. DecodeM d h c => c -> d h
decodeM (FloatABIType -> IO FloatABI) -> IO FloatABIType -> IO FloatABI
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr TargetOptions -> IO FloatABIType
FFI.getFloatABIType Ptr TargetOptions
tOpts
  FloatingPointOperationFusionMode
allowFloatingPointOperationFusion <- FPOpFusionMode -> IO FloatingPointOperationFusionMode
forall (d :: * -> *) h c. DecodeM d h c => c -> d h
decodeM (FPOpFusionMode -> IO FloatingPointOperationFusionMode)
-> IO FPOpFusionMode -> IO FloatingPointOperationFusionMode
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr TargetOptions -> IO FPOpFusionMode
FFI.getAllowFPOpFusion Ptr TargetOptions
tOpts
  ThreadModel
threadModel <- ThreadModel -> IO ThreadModel
forall (d :: * -> *) h c. DecodeM d h c => c -> d h
decodeM (ThreadModel -> IO ThreadModel) -> IO ThreadModel -> IO ThreadModel
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr TargetOptions -> IO ThreadModel
FFI.getThreadModel Ptr TargetOptions
tOpts
  EABIVersion
eabiVersion <- EABI -> IO EABIVersion
forall (d :: * -> *) h c. DecodeM d h c => c -> d h
decodeM (EABI -> IO EABIVersion) -> IO EABI -> IO EABIVersion
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr TargetOptions -> IO EABI
FFI.getEABIVersion Ptr TargetOptions
tOpts
  DebuggerKind
debuggerTuning <- DebuggerKind -> IO DebuggerKind
forall (d :: * -> *) h c. DecodeM d h c => c -> d h
decodeM (DebuggerKind -> IO DebuggerKind)
-> IO DebuggerKind -> IO DebuggerKind
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr TargetOptions -> IO DebuggerKind
FFI.getDebuggerTuning Ptr TargetOptions
tOpts
  FloatingPointDenormalMode
floatingPointDenormalMode <- FPDenormalMode -> IO FloatingPointDenormalMode
forall (d :: * -> *) h c. DecodeM d h c => c -> d h
decodeM (FPDenormalMode -> IO FloatingPointDenormalMode)
-> IO FPDenormalMode -> IO FloatingPointDenormalMode
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr TargetOptions -> IO FPDenormalMode
FFI.getFPDenormalMode Ptr TargetOptions
tOpts
  ExceptionHandling
exceptionModel <- ExceptionHandling -> IO ExceptionHandling
forall (d :: * -> *) h c. DecodeM d h c => c -> d h
decodeM (ExceptionHandling -> IO ExceptionHandling)
-> IO ExceptionHandling -> IO ExceptionHandling
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr TargetOptions -> IO ExceptionHandling
FFI.getExceptionModel Ptr TargetOptions
tOpts
  MachineCodeOptions
machineCodeOptions <- MCTargetOptions -> IO MachineCodeOptions
peekMachineCodeOptions (MCTargetOptions -> IO MachineCodeOptions)
-> IO MCTargetOptions -> IO MachineCodeOptions
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< TargetOptions -> IO MCTargetOptions
machineCodeOptions TargetOptions
opts
  Options -> IO Options
forall (m :: * -> *) a. Monad m => a -> m a
return Options :: Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> DebugCompressionType
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Word32
-> FloatABI
-> FloatingPointOperationFusionMode
-> ThreadModel
-> EABIVersion
-> DebuggerKind
-> FloatingPointDenormalMode
-> ExceptionHandling
-> MachineCodeOptions
-> Options
TO.Options { .. }

-- | get all machine code options
peekMachineCodeOptions :: MCTargetOptions -> IO TO.MachineCodeOptions
peekMachineCodeOptions :: MCTargetOptions -> IO MachineCodeOptions
peekMachineCodeOptions (MCTargetOptions tOpts :: Ptr MCTargetOptions
tOpts) = do
  let gof :: MCTargetOptionFlag -> IO Bool
gof = LLVMBool -> IO Bool
forall (d :: * -> *) h c. DecodeM d h c => c -> d h
decodeM (LLVMBool -> IO Bool)
-> (MCTargetOptionFlag -> IO LLVMBool)
-> MCTargetOptionFlag
-> IO Bool
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Ptr MCTargetOptions -> MCTargetOptionFlag -> IO LLVMBool
FFI.getMCTargetOptionsFlag Ptr MCTargetOptions
tOpts
  Bool
relaxAll
    <- MCTargetOptionFlag -> IO Bool
gof MCTargetOptionFlag
FFI.mcTargetOptionFlagMCRelaxAll
  Bool
noExecutableStack
    <- MCTargetOptionFlag -> IO Bool
gof MCTargetOptionFlag
FFI.mcTargetOptionFlagMCNoExecStack
  Bool
fatalWarnings
    <- MCTargetOptionFlag -> IO Bool
gof MCTargetOptionFlag
FFI.mcTargetOptionFlagMCFatalWarnings
  Bool
noWarnings
    <- MCTargetOptionFlag -> IO Bool
gof MCTargetOptionFlag
FFI.mcTargetOptionFlagMCNoWarn
  Bool
noDeprecatedWarning
    <- MCTargetOptionFlag -> IO Bool
gof MCTargetOptionFlag
FFI.mcTargetOptionFlagMCNoDeprecatedWarn
  Bool
saveTemporaryLabels
    <- MCTargetOptionFlag -> IO Bool
gof MCTargetOptionFlag
FFI.mcTargetOptionFlagMCSaveTempLabels
  Bool
useDwarfDirectory
    <- MCTargetOptionFlag -> IO Bool
gof MCTargetOptionFlag
FFI.mcTargetOptionFlagMCUseDwarfDirectory
  Bool
incrementalLinkerCompatible
    <- MCTargetOptionFlag -> IO Bool
gof MCTargetOptionFlag
FFI.mcTargetOptionFlagMCIncrementalLinkerCompatible
  Bool
pieCopyRelocations
    <- MCTargetOptionFlag -> IO Bool
gof MCTargetOptionFlag
FFI.mcTargetOptionFlagMCPIECopyRelocations
  Bool
showMachineCodeEncoding
    <- MCTargetOptionFlag -> IO Bool
gof MCTargetOptionFlag
FFI.mcTargetOptionFlagShowMCEncoding
  Bool
showMachineCodeInstructions
    <- MCTargetOptionFlag -> IO Bool
gof MCTargetOptionFlag
FFI.mcTargetOptionFlagShowMCInst
  Bool
verboseAssembly
    <- MCTargetOptionFlag -> IO Bool
gof MCTargetOptionFlag
FFI.mcTargetOptionFlagAsmVerbose
  Bool
preserveComentsInAssembly
    <- MCTargetOptionFlag -> IO Bool
gof MCTargetOptionFlag
FFI.mcTargetOptionFlagPreserveAsmComments
  MachineCodeOptions -> IO MachineCodeOptions
forall (m :: * -> *) a. Monad m => a -> m a
return MachineCodeOptions :: Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> MachineCodeOptions
TO.MachineCodeOptions { .. }

-- | <http://llvm.org/doxygen/classllvm_1_1TargetMachine.html>
newtype TargetMachine = TargetMachine (Ptr FFI.TargetMachine)

-- | bracket creation and destruction of a 'TargetMachine'
withTargetMachine ::
    Target
    -> ShortByteString -- ^ triple
    -> ByteString -- ^ cpu
    -> Map CPUFeature Bool -- ^ features
    -> TargetOptions
    -> Reloc.Model
    -> CodeModel.Model
    -> CodeGenOpt.Level
    -> (TargetMachine -> IO a)
    -> IO a
withTargetMachine :: Target
-> ShortByteString
-> ByteString
-> Map CPUFeature Bool
-> TargetOptions
-> Model
-> Model
-> Level
-> (TargetMachine -> IO a)
-> IO a
withTargetMachine
  (Target target :: Ptr Target
target)
  triple :: ShortByteString
triple
  cpu :: ByteString
cpu
  features :: Map CPUFeature Bool
features
  (TargetOptions targetOptions :: Ptr TargetOptions
targetOptions)
  relocModel :: Model
relocModel
  codeModel :: Model
codeModel
  codeGenOptLevel :: Level
codeGenOptLevel = AnyContT IO TargetMachine -> (TargetMachine -> IO a) -> IO a
forall (m :: * -> *) a. AnyContT m a -> forall r. (a -> m r) -> m r
runAnyContT (AnyContT IO TargetMachine -> (TargetMachine -> IO a) -> IO a)
-> AnyContT IO TargetMachine -> (TargetMachine -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ do
  CString
triple <- ShortByteString -> AnyContT IO CString
forall (e :: * -> *) h c. EncodeM e h c => h -> e c
encodeM ShortByteString
triple
  CString
cpu <- ByteString -> AnyContT IO CString
forall (e :: * -> *) h c. EncodeM e h c => h -> e c
encodeM ByteString
cpu
  CString
features <- Map CPUFeature Bool -> AnyContT IO CString
forall (e :: * -> *) h c. EncodeM e h c => h -> e c
encodeM Map CPUFeature Bool
features
  RelocModel
relocModel <- Model -> AnyContT IO RelocModel
forall (e :: * -> *) h c. EncodeM e h c => h -> e c
encodeM Model
relocModel
  CodeModel
codeModel <- Model -> AnyContT IO CodeModel
forall (e :: * -> *) h c. EncodeM e h c => h -> e c
encodeM Model
codeModel
  CodeGenOptLevel
codeGenOptLevel <- Level -> AnyContT IO CodeGenOptLevel
forall (e :: * -> *) h c. EncodeM e h c => h -> e c
encodeM Level
codeGenOptLevel
  (forall r. (TargetMachine -> IO r) -> IO r)
-> AnyContT IO TargetMachine
forall (b :: * -> *) (m :: * -> *) a.
MonadAnyCont b m =>
(forall r. (a -> b r) -> b r) -> m a
anyContToM ((forall r. (TargetMachine -> IO r) -> IO r)
 -> AnyContT IO TargetMachine)
-> (forall r. (TargetMachine -> IO r) -> IO r)
-> AnyContT IO TargetMachine
forall a b. (a -> b) -> a -> b
$ IO (Ptr TargetMachine)
-> (Ptr TargetMachine -> IO ())
-> (Ptr TargetMachine -> IO r)
-> IO r
forall (m :: * -> *) a c b.
MonadMask m =>
m a -> (a -> m c) -> (a -> m b) -> m b
bracket (
      Ptr Target
-> CString
-> CString
-> CString
-> Ptr TargetOptions
-> RelocModel
-> CodeModel
-> CodeGenOptLevel
-> IO (Ptr TargetMachine)
FFI.createTargetMachine
         Ptr Target
target
         CString
triple
         CString
cpu
         CString
features
         Ptr TargetOptions
targetOptions
         RelocModel
relocModel
         CodeModel
codeModel
         CodeGenOptLevel
codeGenOptLevel
      )
      Ptr TargetMachine -> IO ()
FFI.disposeTargetMachine
      ((Ptr TargetMachine -> IO r) -> IO r)
-> ((TargetMachine -> IO r) -> Ptr TargetMachine -> IO r)
-> (TargetMachine -> IO r)
-> IO r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((TargetMachine -> IO r)
-> (Ptr TargetMachine -> TargetMachine)
-> Ptr TargetMachine
-> IO r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr TargetMachine -> TargetMachine
TargetMachine)

targetMachineOptions :: TargetMachine -> IO TargetOptions
targetMachineOptions :: TargetMachine -> IO TargetOptions
targetMachineOptions (TargetMachine tm :: Ptr TargetMachine
tm) = Ptr TargetOptions -> TargetOptions
TargetOptions (Ptr TargetOptions -> TargetOptions)
-> IO (Ptr TargetOptions) -> IO TargetOptions
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr TargetMachine -> IO (Ptr TargetOptions)
FFI.targetMachineOptions Ptr TargetMachine
tm

machineCodeOptions :: TargetOptions -> IO MCTargetOptions
machineCodeOptions :: TargetOptions -> IO MCTargetOptions
machineCodeOptions (TargetOptions to :: Ptr TargetOptions
to) = Ptr MCTargetOptions -> MCTargetOptions
MCTargetOptions (Ptr MCTargetOptions -> MCTargetOptions)
-> IO (Ptr MCTargetOptions) -> IO MCTargetOptions
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr TargetOptions -> IO (Ptr MCTargetOptions)
FFI.machineCodeOptions Ptr TargetOptions
to

-- | <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 -> IO TargetLowering
getTargetLowering (TargetMachine _) = Ptr TargetLowering -> TargetLowering
TargetLowering (Ptr TargetLowering -> TargetLowering)
-> IO (Ptr TargetLowering) -> IO TargetLowering
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> IO (Ptr TargetLowering)
forall a. HasCallStack => String -> a
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 :: IO ()
initializeNativeTarget = do
  Bool
failure <- LLVMBool -> IO Bool
forall (d :: * -> *) h c. DecodeM d h c => c -> d h
decodeM (LLVMBool -> IO Bool) -> IO LLVMBool -> IO Bool
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IO LLVMBool -> IO LLVMBool
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO LLVMBool
FFI.initializeNativeTarget
  Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
failure (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ String -> IO ()
forall (m :: * -> *) a. MonadFail m => String -> m a
fail "native target initialization failed"

-- | the target triple corresponding to the target machine
getTargetMachineTriple :: TargetMachine -> IO ShortByteString
getTargetMachineTriple :: TargetMachine -> IO ShortByteString
getTargetMachineTriple (TargetMachine m :: Ptr TargetMachine
m) = OwnerTransfered CString -> IO ShortByteString
forall (d :: * -> *) h c. DecodeM d h c => c -> d h
decodeM (OwnerTransfered CString -> IO ShortByteString)
-> IO (OwnerTransfered CString) -> IO ShortByteString
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr TargetMachine -> IO (OwnerTransfered CString)
FFI.getTargetMachineTriple Ptr TargetMachine
m

-- | the default target triple that LLVM has been configured to produce code for
getDefaultTargetTriple :: IO ShortByteString
getDefaultTargetTriple :: IO ShortByteString
getDefaultTargetTriple = OwnerTransfered CString -> IO ShortByteString
forall (d :: * -> *) h c. DecodeM d h c => c -> d h
decodeM (OwnerTransfered CString -> IO ShortByteString)
-> IO (OwnerTransfered CString) -> IO ShortByteString
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IO (OwnerTransfered CString)
FFI.getDefaultTargetTriple

-- | a target triple suitable for loading code into the current process
getProcessTargetTriple :: IO ShortByteString
getProcessTargetTriple :: IO ShortByteString
getProcessTargetTriple = OwnerTransfered CString -> IO ShortByteString
forall (d :: * -> *) h c. DecodeM d h c => c -> d h
decodeM (OwnerTransfered CString -> IO ShortByteString)
-> IO (OwnerTransfered CString) -> IO ShortByteString
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IO (OwnerTransfered CString)
FFI.getProcessTargetTriple

-- | the LLVM name for the host CPU
getHostCPUName :: IO ByteString
getHostCPUName :: IO ByteString
getHostCPUName = (Ptr CSize -> IO CString) -> IO ByteString
forall (d :: * -> *) h c. DecodeM d h c => c -> d h
decodeM Ptr CSize -> IO CString
FFI.getHostCPUName

-- | a space-separated list of LLVM feature names supported by the host CPU
getHostCPUFeatures :: IO (Map CPUFeature Bool)
getHostCPUFeatures :: IO (Map CPUFeature Bool)
getHostCPUFeatures =
  OwnerTransfered CString -> IO (Map CPUFeature Bool)
forall (d :: * -> *) h c. DecodeM d h c => c -> d h
decodeM (OwnerTransfered CString -> IO (Map CPUFeature Bool))
-> IO (OwnerTransfered CString) -> IO (Map CPUFeature Bool)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IO (OwnerTransfered CString)
FFI.getHostCPUFeatures

-- | 'DataLayout' to use for the given 'TargetMachine'
getTargetMachineDataLayout :: TargetMachine -> IO DataLayout
getTargetMachineDataLayout :: TargetMachine -> IO DataLayout
getTargetMachineDataLayout (TargetMachine m :: Ptr TargetMachine
m) = do
  ByteString
dlString <- OwnerTransfered CString -> IO ByteString
forall (d :: * -> *) h c. DecodeM d h c => c -> d h
decodeM (OwnerTransfered CString -> IO ByteString)
-> IO (OwnerTransfered CString) -> IO ByteString
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr TargetMachine -> IO (OwnerTransfered CString)
FFI.getTargetMachineDataLayout Ptr TargetMachine
m
  let Right (Just dl :: DataLayout
dl) = Except String (Maybe DataLayout)
-> Either String (Maybe DataLayout)
forall e a. Except e a -> Either e a
runExcept (Except String (Maybe DataLayout)
 -> Either String (Maybe DataLayout))
-> (ByteString -> Except String (Maybe DataLayout))
-> ByteString
-> Either String (Maybe DataLayout)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Endianness -> ByteString -> Except String (Maybe DataLayout)
parseDataLayout Endianness
BigEndian (ByteString -> Either String (Maybe DataLayout))
-> ByteString -> Either String (Maybe DataLayout)
forall a b. (a -> b) -> a -> b
$ ByteString
dlString
  DataLayout -> IO DataLayout
forall (m :: * -> *) a. Monad m => a -> m a
return DataLayout
dl

-- | Initialize all targets so they can be found by 'lookupTarget'
initializeAllTargets :: IO ()
initializeAllTargets :: IO ()
initializeAllTargets = IO ()
FFI.initializeAllTargets

-- | Bracket creation and destruction of a 'TargetMachine' configured for the host.
--
-- This function infers and fills the properties of the host machine
-- (architecture, CPU type, operating system etc.) to construct
-- a 'TargetMachine' value, but other parameters of 'TargetMachine' (the
-- code model, relocation model, and optimization level) have to be
-- provided by the user. For instance, for the JIT-compiled code that you
-- want to dynamically load you probably want to use the 'Reloc.PIC'
-- relocation model.
withHostTargetMachine
  :: Reloc.Model
  -> CodeModel.Model
  -> CodeGenOpt.Level
  -> (TargetMachine -> IO a) -> IO a
withHostTargetMachine :: Model -> Model -> Level -> (TargetMachine -> IO a) -> IO a
withHostTargetMachine relocModel :: Model
relocModel codeModel :: Model
codeModel codeGenOpt :: Level
codeGenOpt f :: TargetMachine -> IO a
f = do
  IO ()
initializeAllTargets
  ShortByteString
triple <- IO ShortByteString
getProcessTargetTriple
  ByteString
cpu <- IO ByteString
getHostCPUName
  Map CPUFeature Bool
features <- IO (Map CPUFeature Bool)
getHostCPUFeatures
  (target :: Target
target, _) <- Maybe ShortByteString
-> ShortByteString -> IO (Target, ShortByteString)
lookupTarget Maybe ShortByteString
forall a. Maybe a
Nothing ShortByteString
triple
  (TargetOptions -> IO a) -> IO a
forall a. (TargetOptions -> IO a) -> IO a
withTargetOptions ((TargetOptions -> IO a) -> IO a)
-> (TargetOptions -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \options :: TargetOptions
options ->
    Target
-> ShortByteString
-> ByteString
-> Map CPUFeature Bool
-> TargetOptions
-> Model
-> Model
-> Level
-> (TargetMachine -> IO a)
-> IO a
forall a.
Target
-> ShortByteString
-> ByteString
-> Map CPUFeature Bool
-> TargetOptions
-> Model
-> Model
-> Level
-> (TargetMachine -> IO a)
-> IO a
withTargetMachine Target
target ShortByteString
triple ByteString
cpu Map CPUFeature Bool
features TargetOptions
options Model
relocModel Model
codeModel Level
codeGenOpt TargetMachine -> IO a
f

-- | Like 'withHostTargetMachine', but assumes the default values for the
-- relocation model, code model, and optimization level ('Reloc.Default',
-- 'CodeModel.Default', 'CodeGenOpt.Default' respectively).
--
-- Note that the 'Reloc.Default' relocation model __is not__ suitable for
-- JIT compilation; use 'withHostTargetMachine' and 'Reloc.PIC' instead.
withHostTargetMachineDefault :: (TargetMachine -> IO a) -> IO a
withHostTargetMachineDefault :: (TargetMachine -> IO a) -> IO a
withHostTargetMachineDefault f :: TargetMachine -> IO a
f = Model -> Model -> Level -> (TargetMachine -> IO a) -> IO a
forall a.
Model -> Model -> Level -> (TargetMachine -> IO a) -> IO a
withHostTargetMachine Model
Reloc.Default Model
CodeModel.Default Level
CodeGenOpt.Default TargetMachine -> IO a
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 -> ShortByteString -> IO (Maybe LibraryFunction)
getLibraryFunction :: TargetLibraryInfo -> ShortByteString -> IO (Maybe LibraryFunction)
getLibraryFunction (TargetLibraryInfo f :: Ptr TargetLibraryInfo
f) name :: ShortByteString
name = (AnyContT IO (Maybe LibraryFunction)
 -> (Maybe LibraryFunction -> IO (Maybe LibraryFunction))
 -> IO (Maybe LibraryFunction))
-> (Maybe LibraryFunction -> IO (Maybe LibraryFunction))
-> AnyContT IO (Maybe LibraryFunction)
-> IO (Maybe LibraryFunction)
forall a b c. (a -> b -> c) -> b -> a -> c
flip AnyContT IO (Maybe LibraryFunction)
-> (Maybe LibraryFunction -> IO (Maybe LibraryFunction))
-> IO (Maybe LibraryFunction)
forall (m :: * -> *) a. AnyContT m a -> forall r. (a -> m r) -> m r
runAnyContT Maybe LibraryFunction -> IO (Maybe LibraryFunction)
forall (m :: * -> *) a. Monad m => a -> m a
return (AnyContT IO (Maybe LibraryFunction) -> IO (Maybe LibraryFunction))
-> AnyContT IO (Maybe LibraryFunction)
-> IO (Maybe LibraryFunction)
forall a b. (a -> b) -> a -> b
$ do
  Ptr LibFunc
libFuncP <- AnyContT IO (Ptr LibFunc)
forall a (m :: * -> *).
(Storable a, MonadAnyCont IO m) =>
m (Ptr a)
alloca :: AnyContT IO (Ptr FFI.LibFunc)
  CString
name <- (ShortByteString -> AnyContT IO CString
forall (e :: * -> *) h c. EncodeM e h c => h -> e c
encodeM ShortByteString
name :: AnyContT IO CString)
  Bool
r <- LLVMBool -> AnyContT IO Bool
forall (d :: * -> *) h c. DecodeM d h c => c -> d h
decodeM (LLVMBool -> AnyContT IO Bool)
-> AnyContT IO LLVMBool -> AnyContT IO Bool
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (IO LLVMBool -> AnyContT IO LLVMBool
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO LLVMBool -> AnyContT IO LLVMBool)
-> IO LLVMBool -> AnyContT IO LLVMBool
forall a b. (a -> b) -> a -> b
$ Ptr TargetLibraryInfo -> CString -> Ptr LibFunc -> IO LLVMBool
FFI.getLibFunc Ptr TargetLibraryInfo
f CString
name Ptr LibFunc
libFuncP)
  Maybe (Ptr LibFunc)
-> (Ptr LibFunc -> AnyContT IO LibraryFunction)
-> AnyContT IO (Maybe LibraryFunction)
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM (if Bool
r then Ptr LibFunc -> Maybe (Ptr LibFunc)
forall a. a -> Maybe a
Just Ptr LibFunc
libFuncP else Maybe (Ptr LibFunc)
forall a. Maybe a
Nothing) ((Ptr LibFunc -> AnyContT IO LibraryFunction)
 -> AnyContT IO (Maybe LibraryFunction))
-> (Ptr LibFunc -> AnyContT IO LibraryFunction)
-> AnyContT IO (Maybe LibraryFunction)
forall a b. (a -> b) -> a -> b
$ LibFunc -> AnyContT IO LibraryFunction
forall (d :: * -> *) h c. DecodeM d h c => c -> d h
decodeM (LibFunc -> AnyContT IO LibraryFunction)
-> (Ptr LibFunc -> AnyContT IO LibFunc)
-> Ptr LibFunc
-> AnyContT IO LibraryFunction
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Ptr LibFunc -> AnyContT IO LibFunc
forall a (m :: * -> *). (Storable a, MonadIO m) => Ptr a -> m a
peek

-- | Get a the current name to be emitted for a 'LibraryFunction'
getLibraryFunctionName :: TargetLibraryInfo -> LibraryFunction -> IO ShortByteString
getLibraryFunctionName :: TargetLibraryInfo -> LibraryFunction -> IO ShortByteString
getLibraryFunctionName (TargetLibraryInfo f :: Ptr TargetLibraryInfo
f) l :: LibraryFunction
l = (AnyContT IO ShortByteString
 -> (ShortByteString -> IO ShortByteString) -> IO ShortByteString)
-> (ShortByteString -> IO ShortByteString)
-> AnyContT IO ShortByteString
-> IO ShortByteString
forall a b c. (a -> b -> c) -> b -> a -> c
flip AnyContT IO ShortByteString
-> (ShortByteString -> IO ShortByteString) -> IO ShortByteString
forall (m :: * -> *) a. AnyContT m a -> forall r. (a -> m r) -> m r
runAnyContT ShortByteString -> IO ShortByteString
forall (m :: * -> *) a. Monad m => a -> m a
return (AnyContT IO ShortByteString -> IO ShortByteString)
-> AnyContT IO ShortByteString -> IO ShortByteString
forall a b. (a -> b) -> a -> b
$ do
  LibFunc
l <- LibraryFunction -> AnyContT IO LibFunc
forall (e :: * -> *) h c. EncodeM e h c => h -> e c
encodeM LibraryFunction
l
  (Ptr CSize -> IO CString) -> AnyContT IO ShortByteString
forall (d :: * -> *) h c. DecodeM d h c => c -> d h
decodeM ((Ptr CSize -> IO CString) -> AnyContT IO ShortByteString)
-> (Ptr CSize -> IO CString) -> AnyContT IO ShortByteString
forall a b. (a -> b) -> a -> b
$ Ptr TargetLibraryInfo -> LibFunc -> Ptr CSize -> IO CString
FFI.libFuncGetName Ptr TargetLibraryInfo
f LibFunc
l

-- | Set the name of the function on the target platform that corresponds to funcName
setLibraryFunctionAvailableWithName ::
  TargetLibraryInfo
  -> LibraryFunction
  -> ShortByteString -- ^ The function name to be emitted
  -> IO ()
setLibraryFunctionAvailableWithName :: TargetLibraryInfo -> LibraryFunction -> ShortByteString -> IO ()
setLibraryFunctionAvailableWithName (TargetLibraryInfo f :: Ptr TargetLibraryInfo
f) libraryFunction :: LibraryFunction
libraryFunction name :: ShortByteString
name = (AnyContT IO () -> (() -> IO ()) -> IO ())
-> (() -> IO ()) -> AnyContT IO () -> IO ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip AnyContT IO () -> (() -> IO ()) -> IO ()
forall (m :: * -> *) a. AnyContT m a -> forall r. (a -> m r) -> m r
runAnyContT () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return (AnyContT IO () -> IO ()) -> AnyContT IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
  CString
name <- ShortByteString -> AnyContT IO CString
forall (e :: * -> *) h c. EncodeM e h c => h -> e c
encodeM ShortByteString
name
  LibFunc
libraryFunction <- LibraryFunction -> AnyContT IO LibFunc
forall (e :: * -> *) h c. EncodeM e h c => h -> e c
encodeM LibraryFunction
libraryFunction
  IO () -> AnyContT IO ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> AnyContT IO ()) -> IO () -> AnyContT IO ()
forall a b. (a -> b) -> a -> b
$ Ptr TargetLibraryInfo -> LibFunc -> CString -> IO ()
FFI.libFuncSetAvailableWithName Ptr TargetLibraryInfo
f LibFunc
libraryFunction CString
name

-- | look up information about the library functions available on a given platform
withTargetLibraryInfo ::
  ShortByteString -- ^ triple
  -> (TargetLibraryInfo -> IO a)
  -> IO a
withTargetLibraryInfo :: ShortByteString -> (TargetLibraryInfo -> IO a) -> IO a
withTargetLibraryInfo triple :: ShortByteString
triple f :: TargetLibraryInfo -> IO a
f = (AnyContT IO a -> (a -> IO a) -> IO a)
-> (a -> IO a) -> AnyContT IO a -> IO a
forall a b c. (a -> b -> c) -> b -> a -> c
flip AnyContT IO a -> (a -> IO a) -> IO a
forall (m :: * -> *) a. AnyContT m a -> forall r. (a -> m r) -> m r
runAnyContT a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (AnyContT IO a -> IO a) -> AnyContT IO a -> IO a
forall a b. (a -> b) -> a -> b
$ do
  CString
triple <- ShortByteString -> AnyContT IO CString
forall (e :: * -> *) h c. EncodeM e h c => h -> e c
encodeM ShortByteString
triple
  IO a -> AnyContT IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO a -> AnyContT IO a) -> IO a -> AnyContT IO a
forall a b. (a -> b) -> a -> b
$ IO (Ptr TargetLibraryInfo)
-> (Ptr TargetLibraryInfo -> IO ())
-> (Ptr TargetLibraryInfo -> IO a)
-> IO a
forall (m :: * -> *) a c b.
MonadMask m =>
m a -> (a -> m c) -> (a -> m b) -> m b
bracket (CString -> IO (Ptr TargetLibraryInfo)
FFI.createTargetLibraryInfo CString
triple) Ptr TargetLibraryInfo -> IO ()
FFI.disposeTargetLibraryInfo (TargetLibraryInfo -> IO a
f (TargetLibraryInfo -> IO a)
-> (Ptr TargetLibraryInfo -> TargetLibraryInfo)
-> Ptr TargetLibraryInfo
-> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr TargetLibraryInfo -> TargetLibraryInfo
TargetLibraryInfo)