llvm-data-interop-0.3.0: src/LLVM/Internal/Interop.chs
{-# LANGUAGE ForeignFunctionInterface, DeriveDataTypeable, RankNTypes, OverloadedStrings, CPP #-}
module LLVM.Internal.Interop where
import Control.Applicative
import Control.Monad ( when )
import Control.Monad.Trans ( MonadIO, liftIO )
import Data.Array.Storable ( getElems )
#if __GLASGOW_HASKELL__ >= 704
import Data.Array.Unsafe ( unsafeForeignPtrToStorableArray )
#else
import Data.Array.Storable ( unsafeForeignPtrToStorableArray )
#endif
import qualified Data.ByteString.Char8 as BS
import Data.Int
import Data.Text ( Text )
import Data.Text.Encoding ( decodeUtf8 )
import Foreign.C
import Foreign.ForeignPtr
import Foreign.Marshal.Utils
import Foreign.Ptr
import Foreign.Storable
import Data.LLVM.Types
#include "c++/marshal.h"
{#enum TypeTag {} deriving (Show, Eq) #}
{#enum ValueTag {underscoreToCase} deriving (Show, Eq) #}
{#enum MetaTag {underscoreToCase} deriving (Show, Eq) #}
data CModule
{#pointer *CModule as ModulePtr -> CModule #}
makeText :: CString -> IO Text
makeText p = do
s <- BS.packCString p
return (decodeUtf8 s)
cModuleIdentifier :: ModulePtr -> IO Text
cModuleIdentifier m = ({#get CModule->moduleIdentifier#} m) >>= makeText
cModuleDataLayout :: ModulePtr -> IO Text
cModuleDataLayout m = ({#get CModule->moduleDataLayout#} m) >>= makeText
cModuleTargetTriple :: ModulePtr -> IO Text
cModuleTargetTriple m = ({#get CModule->targetTriple#} m) >>= makeText
cModuleInlineAsm :: ModulePtr -> IO Text
cModuleInlineAsm m = ({#get CModule->moduleInlineAsm#} m) >>= makeText
cModuleHasError :: ModulePtr -> IO Bool
cModuleHasError m = toBool <$> ({#get CModule->hasError#} m)
cModuleErrorMessage :: ModulePtr -> IO (Maybe String)
cModuleErrorMessage m = do
hasError <- cModuleHasError m
case hasError of
True -> do
msgPtr <- ({#get CModule->errMsg#} m)
s <- peekCString msgPtr
return (Just s)
False -> return Nothing
cModuleLittleEndian :: ModulePtr -> IO Bool
cModuleLittleEndian m = toBool <$> ({#get CModule->littleEndian#} m)
cModulePointerSize :: ModulePtr -> IO Int
cModulePointerSize m = fromIntegral <$> ({#get CModule->pointerSize#} m)
cModuleGlobalVariables :: ModulePtr -> IO [ValuePtr]
cModuleGlobalVariables m =
peekArray m {#get CModule->globalVariables#} {#get CModule->numGlobalVariables#}
cModuleGlobalAliases :: ModulePtr -> IO [ValuePtr]
cModuleGlobalAliases m =
peekArray m ({#get CModule->globalAliases#}) ({#get CModule->numGlobalAliases#})
cModuleFunctions :: ModulePtr -> IO [ValuePtr]
cModuleFunctions m =
peekArray m ({#get CModule->functions#}) ({#get CModule->numFunctions#})
cModuleEnumMetadata :: ModulePtr -> IO [MetaPtr]
cModuleEnumMetadata m =
peekArray m {#get CModule->enumMetadata#} {#get CModule->numEnumMetadata#}
cModuleRetainedTypeMetadata :: ModulePtr -> IO [MetaPtr]
cModuleRetainedTypeMetadata m =
peekArray m {#get CModule->retainedTypeMetadata#} {#get CModule->numRetainedTypes#}
cModuleTypes :: ModulePtr -> IO [TypePtr]
cModuleTypes m =
peekArray m {#get CModule->types#} {#get CModule->numTypes#}
peekArray :: forall a b c e . (Integral c, Storable e) =>
a -> (a -> IO (Ptr b)) -> (a -> IO c) -> IO [e]
peekArray obj arrAccessor sizeAccessor = do
nElts <- sizeAccessor obj
arrPtr <- arrAccessor obj
case nElts == 0 || arrPtr == nullPtr of
True -> return []
False -> do
fArrPtr <- newForeignPtr_ (castPtr arrPtr)
let elementCount :: Int
elementCount = fromIntegral nElts
arr <- unsafeForeignPtrToStorableArray fArrPtr (1, elementCount)
getElems arr
data CType
{#pointer *CType as TypePtr -> CType #}
cTypeTag :: TypePtr -> IO TypeTag
cTypeTag t = toEnum . fromIntegral <$> {#get CType->typeTag#} t
cTypeSize :: TypePtr -> IO Int
cTypeSize t = fromIntegral <$> {#get CType->size#} t
cTypeIsVarArg :: TypePtr -> IO Bool
cTypeIsVarArg t = toBool <$> {#get CType->isVarArg#} t
cTypeIsPacked :: TypePtr -> IO Bool
cTypeIsPacked t = toBool <$> {#get CType->isPacked#} t
cTypeList :: TypePtr -> IO [TypePtr]
cTypeList t =
peekArray t {#get CType->typeList#} {#get CType->typeListLen#}
cTypeInner :: TypePtr -> IO TypePtr
cTypeInner = {#get CType->innerType#}
cTypeName :: TypePtr -> IO (Maybe String)
cTypeName t = do
n <- optionalField {#get CType->name#} t
case n of
Nothing -> return Nothing
Just n' -> do
s <- peekCString n'
return (Just s)
cTypeAddrSpace :: TypePtr -> IO Int
cTypeAddrSpace t = fromIntegral <$> {#get CType->addrSpace#} t
cTypeSizeInBytes :: TypePtr -> IO Int
cTypeSizeInBytes t = fromIntegral <$> {#get CType->sizeInBytes#} t
data CValue
{#pointer *CValue as ValuePtr -> CValue #}
data CMeta
{#pointer *CMeta as MetaPtr -> CMeta #}
cValueTag :: ValuePtr -> IO ValueTag
cValueTag v = toEnum . fromIntegral <$> ({#get CValue->valueTag#} v)
cValueType :: ValuePtr -> IO TypePtr
cValueType = {#get CValue->valueType#}
cValueName :: (InternString m) => ValuePtr -> m (Maybe Identifier)
cValueName v = do
tag <- liftIO $ cValueTag v
namePtr <- liftIO $ ({#get CValue->name#}) v
case namePtr == nullPtr of
True -> return Nothing
False -> do
rawName <- liftIO $ makeText namePtr
name <- internString rawName
rawIdent <- case tag of
ValFunction -> return $! makeGlobalIdentifier name
ValGlobalvariable -> return $! makeGlobalIdentifier name
ValAlias -> return $! makeGlobalIdentifier name
_ -> return $! makeLocalIdentifier name
ident <- internIdentifier rawIdent
return $! (Just ident)
cValueMetadata :: ValuePtr -> IO [MetaPtr]
cValueMetadata v = peekArray v {#get CValue->md#} {#get CValue->numMetadata#}
cValueSrcLoc :: ValuePtr -> IO MetaPtr
cValueSrcLoc = {#get CValue->srcLoc#}
cValueData :: ValuePtr -> IO (Ptr ())
cValueData = {#get CValue->data#}
cMetaTypeTag :: MetaPtr -> IO MetaTag
cMetaTypeTag v = toEnum . fromIntegral <$> {#get CMeta->metaTag #} v
cMetaTag :: MetaPtr -> IO DW_TAG
cMetaTag p = do
t <- {#get CMeta->tag#} p
case dw_tag t of
Nothing -> return DW_TAG_unspecified_type
Just t' -> return t'
cMetaArrayElts :: MetaPtr -> IO [Maybe MetaPtr]
cMetaArrayElts p = map convertNull <$>
peekArray p {#get CMeta->u.metaArrayInfo.arrayElts#} {#get CMeta->u.metaArrayInfo.arrayLen#}
where
convertNull ptr =
case ptr == nullPtr of
True -> Nothing
False -> Just ptr
cMetaEnumeratorName :: InternString m => MetaPtr -> m Text
cMetaEnumeratorName = shareString {#get CMeta->u.metaEnumeratorInfo.enumName#}
cMetaEnumeratorValue :: MetaPtr -> IO Int64
cMetaEnumeratorValue p = fromIntegral <$> {#get CMeta->u.metaEnumeratorInfo.enumValue#} p
cMetaGlobalContext :: MetaPtr -> IO (Maybe MetaPtr)
cMetaGlobalContext = optionalField {#get CMeta->u.metaGlobalInfo.context #}
cMetaGlobalName :: InternString m => MetaPtr -> m Text
cMetaGlobalName = shareString {#get CMeta->u.metaGlobalInfo.name#}
cMetaGlobalDisplayName :: InternString m => MetaPtr -> m Text
cMetaGlobalDisplayName = shareString {#get CMeta->u.metaGlobalInfo.displayName#}
cMetaGlobalLinkageName :: InternString m => MetaPtr -> m Text
cMetaGlobalLinkageName = shareString {#get CMeta->u.metaGlobalInfo.linkageName#}
-- cMetaGlobalCompileUnit :: MetaPtr -> IO MetaPtr
-- cMetaGlobalCompileUnit = {#get CMeta->u.metaGlobalInfo.compileUnit#}
cMetaGlobalLine :: MetaPtr -> IO Int32
cMetaGlobalLine p = fromIntegral <$> {#get CMeta->u.metaGlobalInfo.lineNumber#} p
cMetaGlobalType :: MetaPtr -> IO (Maybe MetaPtr)
cMetaGlobalType = optionalField {#get CMeta->u.metaGlobalInfo.globalType#}
cMetaGlobalIsLocal :: MetaPtr -> IO Bool
cMetaGlobalIsLocal p = toBool <$> {#get CMeta->u.metaGlobalInfo.isLocalToUnit#} p
cMetaGlobalIsDefinition :: MetaPtr -> IO Bool
cMetaGlobalIsDefinition p = toBool <$> {#get CMeta->u.metaGlobalInfo.isDefinition#} p
cMetaLocationLine :: MetaPtr -> IO Int32
cMetaLocationLine p = fromIntegral <$> {#get CMeta->u.metaLocationInfo.lineNumber#} p
cMetaLocationColumn :: MetaPtr -> IO Int32
cMetaLocationColumn p = fromIntegral <$> {#get CMeta->u.metaLocationInfo.columnNumber#} p
cMetaLocationScope :: MetaPtr -> IO (Maybe MetaPtr)
cMetaLocationScope = optionalField {#get CMeta->u.metaLocationInfo.scope#}
cMetaSubrangeLo :: MetaPtr -> IO Int64
cMetaSubrangeLo p = fromIntegral <$> {#get CMeta->u.metaSubrangeInfo.lo#} p
cMetaSubrangeHi :: MetaPtr -> IO Int64
cMetaSubrangeHi p = fromIntegral <$> {#get CMeta->u.metaSubrangeInfo.hi#} p
cMetaTemplateTypeContext :: MetaPtr -> IO (Maybe MetaPtr)
cMetaTemplateTypeContext = optionalField {#get CMeta->u.metaTemplateTypeInfo.context#}
cMetaTemplateTypeName :: InternString m => MetaPtr -> m Text
cMetaTemplateTypeName = shareString {#get CMeta->u.metaTemplateTypeInfo.name#}
cMetaTemplateTypeType :: MetaPtr -> IO (Maybe MetaPtr)
cMetaTemplateTypeType = optionalField {#get CMeta->u.metaTemplateTypeInfo.type#}
cMetaTemplateTypeLine :: MetaPtr -> IO Int32
cMetaTemplateTypeLine p = fromIntegral <$> {#get CMeta->u.metaTemplateTypeInfo.lineNumber#} p
cMetaTemplateTypeColumn :: MetaPtr -> IO Int32
cMetaTemplateTypeColumn p = fromIntegral <$> {#get CMeta->u.metaTemplateTypeInfo.columnNumber#} p
cMetaTemplateValueContext :: MetaPtr -> IO (Maybe MetaPtr)
cMetaTemplateValueContext = optionalField {#get CMeta->u.metaTemplateValueInfo.context#}
cMetaTemplateValueName :: InternString m => MetaPtr -> m Text
cMetaTemplateValueName = shareString {#get CMeta->u.metaTemplateValueInfo.name#}
cMetaTemplateValueType :: MetaPtr -> IO (Maybe MetaPtr)
cMetaTemplateValueType = optionalField {#get CMeta->u.metaTemplateValueInfo.type#}
cMetaTemplateValueValue :: MetaPtr -> IO Int64
cMetaTemplateValueValue p = fromIntegral <$> {#get CMeta->u.metaTemplateValueInfo.value#} p
cMetaTemplateValueLine :: MetaPtr -> IO Int32
cMetaTemplateValueLine p = fromIntegral <$> {#get CMeta->u.metaTemplateValueInfo.lineNumber#} p
cMetaTemplateValueColumn :: MetaPtr -> IO Int32
cMetaTemplateValueColumn p = fromIntegral <$> {#get CMeta->u.metaTemplateValueInfo.columnNumber#} p
cMetaVariableContext :: MetaPtr -> IO (Maybe MetaPtr)
cMetaVariableContext = optionalField {#get CMeta->u.metaVariableInfo.context#}
cMetaVariableName :: InternString m => MetaPtr -> m Text
cMetaVariableName = shareString {#get CMeta->u.metaVariableInfo.name#}
-- cMetaVariableCompileUnit :: MetaPtr -> IO MetaPtr
-- cMetaVariableCompileUnit = {#get CMeta->u.metaVariableInfo.compileUnit#}
cMetaVariableLine :: MetaPtr -> IO Int32
cMetaVariableLine p = fromIntegral <$> {#get CMeta->u.metaVariableInfo.lineNumber#} p
cMetaVariableArgNumber :: MetaPtr -> IO Int32
cMetaVariableArgNumber p = fromIntegral <$> {#get CMeta->u.metaVariableInfo.argNumber#} p
cMetaVariableType :: MetaPtr -> IO (Maybe MetaPtr)
cMetaVariableType = optionalField {#get CMeta->u.metaVariableInfo.type#}
cMetaVariableIsArtificial :: MetaPtr -> IO Bool
cMetaVariableIsArtificial p = toBool <$> {#get CMeta->u.metaVariableInfo.isArtificial#} p
cMetaVariableHasComplexAddress :: MetaPtr -> IO Bool
cMetaVariableHasComplexAddress p = toBool <$> {#get CMeta->u.metaVariableInfo.hasComplexAddress #} p
cMetaVariableAddrElements :: MetaPtr -> IO [Int64]
cMetaVariableAddrElements p = do
ca <- cMetaVariableHasComplexAddress p
case ca of
True -> peekArray p {#get CMeta->u.metaVariableInfo.addrElements#} {#get CMeta->u.metaVariableInfo.numAddrElements#}
False -> return []
cMetaVariableIsBlockByRefVar :: MetaPtr -> IO Bool
cMetaVariableIsBlockByRefVar p = toBool <$> {#get CMeta->u.metaVariableInfo.isBlockByRefVar#} p
cMetaCompileUnitLanguage :: MetaPtr -> IO DW_LANG
cMetaCompileUnitLanguage p = dw_lang <$> {#get CMeta->u.metaCompileUnitInfo.language#} p
cMetaCompileUnitFilename :: InternString m => MetaPtr -> m Text
cMetaCompileUnitFilename = shareString {#get CMeta->u.metaCompileUnitInfo.filename#}
cMetaCompileUnitDirectory :: InternString m => MetaPtr -> m Text
cMetaCompileUnitDirectory = shareString {#get CMeta->u.metaCompileUnitInfo.directory#}
cMetaCompileUnitProducer :: InternString m => MetaPtr -> m Text
cMetaCompileUnitProducer = shareString {#get CMeta->u.metaCompileUnitInfo.producer#}
cMetaCompileUnitIsMain :: MetaPtr -> IO Bool
cMetaCompileUnitIsMain p = toBool <$> {#get CMeta->u.metaCompileUnitInfo.isMain#} p
cMetaCompileUnitIsOptimized :: MetaPtr -> IO Bool
cMetaCompileUnitIsOptimized p = toBool <$> {#get CMeta->u.metaCompileUnitInfo.isOptimized#} p
cMetaCompileUnitFlags :: InternString m => MetaPtr -> m Text
cMetaCompileUnitFlags = shareString {#get CMeta->u.metaCompileUnitInfo.flags#}
cMetaCompileUnitRuntimeVersion :: MetaPtr -> IO Int32
cMetaCompileUnitRuntimeVersion p = fromIntegral <$> {#get CMeta->u.metaCompileUnitInfo.runtimeVersion#} p
cMetaCompileUnitEnumTypes :: MetaPtr -> IO (Maybe MetaPtr)
cMetaCompileUnitEnumTypes = optionalField {#get CMeta->u.metaCompileUnitInfo.enumTypes#}
cMetaCompileUnitRetainedTypes :: MetaPtr -> IO (Maybe MetaPtr)
cMetaCompileUnitRetainedTypes = optionalField {#get CMeta->u.metaCompileUnitInfo.retainedTypes#}
cMetaCompileUnitSubprograms :: MetaPtr -> IO (Maybe MetaPtr)
cMetaCompileUnitSubprograms = optionalField {#get CMeta->u.metaCompileUnitInfo.subprograms#}
cMetaCompileUnitGlobalVariables :: MetaPtr -> IO (Maybe MetaPtr)
cMetaCompileUnitGlobalVariables = optionalField {#get CMeta->u.metaCompileUnitInfo.globalVariables#}
cMetaFileFilename :: InternString m => MetaPtr -> m Text
cMetaFileFilename = shareString {#get CMeta->u.metaFileInfo.filename#}
cMetaFileDirectory :: InternString m => MetaPtr -> m Text
cMetaFileDirectory = shareString {#get CMeta->u.metaFileInfo.directory#}
-- cMetaFileCompileUnit :: MetaPtr -> IO MetaPtr
-- cMetaFileCompileUnit = {#get CMeta->u.metaFileInfo.compileUnit#}
cMetaLexicalBlockContext :: MetaPtr -> IO (Maybe MetaPtr)
cMetaLexicalBlockContext = optionalField {#get CMeta->u.metaLexicalBlockInfo.context#}
cMetaLexicalBlockLine :: MetaPtr -> IO Int32
cMetaLexicalBlockLine p = fromIntegral <$> {#get CMeta->u.metaLexicalBlockInfo.lineNumber#} p
cMetaLexicalBlockColumn :: MetaPtr -> IO Int32
cMetaLexicalBlockColumn p = fromIntegral <$> {#get CMeta->u.metaLexicalBlockInfo.columnNumber#} p
cMetaNamespaceContext :: MetaPtr -> IO (Maybe MetaPtr)
cMetaNamespaceContext = optionalField {#get CMeta->u.metaNamespaceInfo.context#}
cMetaNamespaceName :: InternString m => MetaPtr -> m Text
cMetaNamespaceName = shareString {#get CMeta->u.metaNamespaceInfo.name#}
-- cMetaNamespaceCompileUnit :: MetaPtr -> IO MetaPtr
-- cMetaNamespaceCompileUnit = {#get CMeta->u.metaNamespaceInfo.compileUnit#}
cMetaNamespaceLine :: MetaPtr -> IO Int32
cMetaNamespaceLine p = fromIntegral <$> {#get CMeta->u.metaNamespaceInfo.lineNumber#} p
cMetaSubprogramContext :: MetaPtr -> IO (Maybe MetaPtr)
cMetaSubprogramContext = optionalField {#get CMeta->u.metaSubprogramInfo.context#}
cMetaSubprogramName :: InternString m => MetaPtr -> m Text
cMetaSubprogramName = shareString {#get CMeta->u.metaSubprogramInfo.name#}
cMetaSubprogramDisplayName :: InternString m => MetaPtr -> m Text
cMetaSubprogramDisplayName = shareString {#get CMeta->u.metaSubprogramInfo.displayName#}
cMetaSubprogramLinkageName :: InternString m => MetaPtr -> m Text
cMetaSubprogramLinkageName = shareString {#get CMeta->u.metaSubprogramInfo.linkageName#}
-- cMetaSubprogramCompileUnit :: MetaPtr -> IO MetaPtr
-- cMetaSubprogramCompileUnit = {#get CMeta->u.metaSubprogramInfo.compileUnit#}
cMetaSubprogramLine :: MetaPtr -> IO Int32
cMetaSubprogramLine p = fromIntegral <$> {#get CMeta->u.metaSubprogramInfo.lineNumber#} p
cMetaSubprogramType :: MetaPtr -> IO (Maybe MetaPtr)
cMetaSubprogramType = optionalField {#get CMeta->u.metaSubprogramInfo.type#}
cMetaSubprogramIsLocal :: MetaPtr -> IO Bool
cMetaSubprogramIsLocal p = toBool <$> {#get CMeta->u.metaSubprogramInfo.isLocalToUnit#} p
cMetaSubprogramIsDefinition :: MetaPtr -> IO Bool
cMetaSubprogramIsDefinition p = toBool <$> {#get CMeta->u.metaSubprogramInfo.isDefinition#} p
cMetaSubprogramVirtuality :: MetaPtr -> IO DW_VIRTUALITY
cMetaSubprogramVirtuality p = dw_virtuality <$> {#get CMeta->u.metaSubprogramInfo.virtuality#} p
cMetaSubprogramVirtualIndex :: MetaPtr -> IO Int32
cMetaSubprogramVirtualIndex p = fromIntegral <$> {#get CMeta->u.metaSubprogramInfo.virtualIndex#} p
cMetaSubprogramContainingType :: MetaPtr -> IO (Maybe MetaPtr)
cMetaSubprogramContainingType = optionalField {#get CMeta->u.metaSubprogramInfo.containingType#}
cMetaSubprogramIsArtificial :: MetaPtr -> IO Bool
cMetaSubprogramIsArtificial p = toBool <$> {#get CMeta->u.metaSubprogramInfo.isArtificial#} p
cMetaSubprogramIsPrivate :: MetaPtr -> IO Bool
cMetaSubprogramIsPrivate p = toBool <$> {#get CMeta->u.metaSubprogramInfo.isPrivate#} p
cMetaSubprogramIsProtected :: MetaPtr -> IO Bool
cMetaSubprogramIsProtected p = toBool <$> {#get CMeta->u.metaSubprogramInfo.isProtected#} p
cMetaSubprogramIsExplicit :: MetaPtr -> IO Bool
cMetaSubprogramIsExplicit p = toBool <$> {#get CMeta->u.metaSubprogramInfo.isExplicit#} p
cMetaSubprogramIsPrototyped :: MetaPtr -> IO Bool
cMetaSubprogramIsPrototyped p = toBool <$> {#get CMeta->u.metaSubprogramInfo.isPrototyped#} p
cMetaSubprogramIsOptimized :: MetaPtr -> IO Bool
cMetaSubprogramIsOptimized p = toBool <$> {#get CMeta->u.metaSubprogramInfo.isOptimized#} p
cMetaTypeContext :: MetaPtr -> IO (Maybe MetaPtr)
cMetaTypeContext = optionalField {#get CMeta->u.metaTypeInfo.context#}
cMetaTypeName :: InternString m => MetaPtr -> m Text
cMetaTypeName = shareString {#get CMeta->u.metaTypeInfo.name#}
-- cMetaTypeCompileUnit :: MetaPtr -> IO (Maybe MetaPtr)
-- cMetaTypeCompileUnit = optionalField {#get CMeta->u.metaTypeInfo.compileUnit#}
-- cMetaTypeFile :: MetaPtr -> IO (Maybe MetaPtr)
-- cMetaTypeFile = optionalField {#get CMeta->u.metaTypeInfo.file#}
cMetaTypeLine :: MetaPtr -> IO Int32
cMetaTypeLine p = fromIntegral <$> {#get CMeta->u.metaTypeInfo.lineNumber#} p
cMetaTypeSize :: MetaPtr -> IO Int64
cMetaTypeSize p = fromIntegral <$> {#get CMeta->u.metaTypeInfo.sizeInBits#} p
cMetaTypeAlign :: MetaPtr -> IO Int64
cMetaTypeAlign p = fromIntegral <$> {#get CMeta->u.metaTypeInfo.alignInBits#} p
cMetaTypeOffset :: MetaPtr -> IO Int64
cMetaTypeOffset p = fromIntegral <$> {#get CMeta->u.metaTypeInfo.offsetInBits#} p
cMetaTypeFlags :: MetaPtr -> IO Int32
cMetaTypeFlags p = fromIntegral <$> {#get CMeta->u.metaTypeInfo.flags#} p
cMetaTypeIsPrivate :: MetaPtr -> IO Bool
cMetaTypeIsPrivate p = toBool <$> {#get CMeta->u.metaTypeInfo.isPrivate#} p
cMetaTypeIsProtected :: MetaPtr -> IO Bool
cMetaTypeIsProtected p = toBool <$> {#get CMeta->u.metaTypeInfo.isProtected#} p
cMetaTypeIsForward :: MetaPtr -> IO Bool
cMetaTypeIsForward p = toBool <$> {#get CMeta->u.metaTypeInfo.isForward#} p
cMetaTypeIsByRefStruct :: MetaPtr -> IO Bool
cMetaTypeIsByRefStruct p = toBool <$> {#get CMeta->u.metaTypeInfo.isByRefStruct#} p
cMetaTypeIsVirtual :: MetaPtr -> IO Bool
cMetaTypeIsVirtual p = toBool <$> {#get CMeta->u.metaTypeInfo.isVirtual#} p
cMetaTypeIsArtificial :: MetaPtr -> IO Bool
cMetaTypeIsArtificial p = toBool <$> {#get CMeta->u.metaTypeInfo.isArtificial#} p
cMetaTypeDirectory :: InternString m => MetaPtr -> m Text
cMetaTypeDirectory = shareString {#get CMeta->u.metaTypeInfo.directory#}
cMetaTypeFilename :: InternString m => MetaPtr -> m Text
cMetaTypeFilename = shareString {#get CMeta->u.metaTypeInfo.filename#}
cMetaTypeEncoding :: MetaPtr -> IO DW_ATE
cMetaTypeEncoding p = dw_ate <$> {#get CMeta->u.metaTypeInfo.encoding#} p
cMetaTypeDerivedFrom :: MetaPtr -> IO (Maybe MetaPtr)
cMetaTypeDerivedFrom = optionalField {#get CMeta->u.metaTypeInfo.typeDerivedFrom#}
cMetaTypeCompositeComponents :: MetaPtr -> IO (Maybe MetaPtr)
cMetaTypeCompositeComponents = optionalField {#get CMeta->u.metaTypeInfo.typeArray#}
cMetaTypeRuntimeLanguage :: MetaPtr -> IO Int32
cMetaTypeRuntimeLanguage p = fromIntegral <$> {#get CMeta->u.metaTypeInfo.runTimeLang#} p
cMetaTypeContainingType :: MetaPtr -> IO (Maybe MetaPtr)
cMetaTypeContainingType = optionalField {#get CMeta->u.metaTypeInfo.containingType#}
cMetaTypeTemplateParams :: MetaPtr -> IO (Maybe MetaPtr)
cMetaTypeTemplateParams = optionalField {#get CMeta->u.metaTypeInfo.templateParams#}
cMetaUnknownRepr :: InternString m => MetaPtr -> m Text
cMetaUnknownRepr = shareString {#get CMeta->u.metaUnknownInfo.repr#}
optionalField :: (a -> IO (Ptr b)) -> a -> IO (Maybe (Ptr b))
optionalField accessor p = do
v <- accessor p
case v == nullPtr of
True -> return Nothing
False -> return (Just v)
class MonadIO m => InternString m where
internString :: Text -> m Text
internIdentifier :: Identifier -> m Identifier
-- | This helper converts C char* strings into Texts, sharing
-- identical bytestrings on the Haskell side. This is a simple
-- space-saving optimization (assuming the entire cache is garbage
-- collected)
shareString :: InternString m => (a -> IO CString) -> a -> m Text
shareString accessor ptr = do
sp <- liftIO $ accessor ptr
str <- case sp == nullPtr of
False -> liftIO $ BS.packCString sp
True -> return $ BS.pack ""
internString (decodeUtf8 str)
data CGlobalInfo
{#pointer *CGlobalInfo as GlobalInfoPtr -> CGlobalInfo #}
cGlobalIsExternal :: GlobalInfoPtr -> IO Bool
cGlobalIsExternal g = toBool <$> ({#get CGlobalInfo->isExternal#} g)
cGlobalAlignment :: GlobalInfoPtr -> IO Int64
cGlobalAlignment g = fromIntegral <$> ({#get CGlobalInfo->alignment#} g)
cGlobalVisibility :: GlobalInfoPtr -> IO VisibilityStyle
cGlobalVisibility g = toEnum . fromIntegral <$> ({#get CGlobalInfo->visibility#} g)
cGlobalLinkage :: GlobalInfoPtr -> IO LinkageType
cGlobalLinkage g = toEnum . fromIntegral <$> ({#get CGlobalInfo->linkage#} g)
cGlobalSection :: GlobalInfoPtr -> IO (Maybe Text)
cGlobalSection g = do
s <- {#get CGlobalInfo->section#} g
case s == nullPtr of
True -> return Nothing
False -> do
bs <- BS.packCString s
return $! Just (decodeUtf8 bs)
cGlobalInitializer :: GlobalInfoPtr -> IO ValuePtr
cGlobalInitializer = {#get CGlobalInfo->initializer#}
cGlobalIsThreadLocal :: GlobalInfoPtr -> IO Bool
cGlobalIsThreadLocal g = toBool <$> ({#get CGlobalInfo->isThreadLocal#} g)
cGlobalAliasee :: GlobalInfoPtr -> IO ValuePtr
cGlobalAliasee = {#get CGlobalInfo->aliasee#}
cGlobalIsConstant :: GlobalInfoPtr -> IO Bool
cGlobalIsConstant g = toBool <$> {#get CGlobalInfo->isConstant#} g
data CFunctionInfo
{#pointer *CFunctionInfo as FunctionInfoPtr -> CFunctionInfo #}
cFunctionIsExternal :: FunctionInfoPtr -> IO Bool
cFunctionIsExternal f = toBool <$> {#get CFunctionInfo->isExternal#} f
cFunctionAlignment :: FunctionInfoPtr -> IO Int64
cFunctionAlignment f = fromIntegral <$> {#get CFunctionInfo->alignment#} f
cFunctionVisibility :: FunctionInfoPtr -> IO VisibilityStyle
cFunctionVisibility f = toEnum . fromIntegral <$> {#get CFunctionInfo->visibility#} f
cFunctionLinkage :: FunctionInfoPtr -> IO LinkageType
cFunctionLinkage f = toEnum . fromIntegral <$> {#get CFunctionInfo->linkage#} f
cFunctionSection :: FunctionInfoPtr -> IO (Maybe Text)
cFunctionSection f = do
s <- {#get CFunctionInfo->section#} f
case s == nullPtr of
True -> return Nothing
False -> do
bs <- BS.packCString s
return $! Just (decodeUtf8 bs)
cFunctionIsVarArg :: FunctionInfoPtr -> IO Bool
cFunctionIsVarArg f = toBool <$> {#get CFunctionInfo->isVarArg#} f
cFunctionCallingConvention :: FunctionInfoPtr -> IO CallingConvention
cFunctionCallingConvention f = toEnum . fromIntegral <$> {#get CFunctionInfo->callingConvention#} f
cFunctionGCName :: FunctionInfoPtr -> IO (Maybe Text)
cFunctionGCName f = do
s <- {#get CFunctionInfo->gcName#} f
case s == nullPtr of
True -> return Nothing
False -> do
bs <- BS.packCString s
return $! Just (decodeUtf8 bs)
cFunctionArguments :: FunctionInfoPtr -> IO [ValuePtr]
cFunctionArguments f =
peekArray f {#get CFunctionInfo->arguments#} {#get CFunctionInfo->argListLen#}
cFunctionBlocks :: FunctionInfoPtr -> IO [ValuePtr]
cFunctionBlocks f =
peekArray f {#get CFunctionInfo->body#} {#get CFunctionInfo->blockListLen#}
data CArgInfo
{#pointer *CArgumentInfo as ArgInfoPtr -> CArgInfo #}
cArgInfoHasSRet :: ArgInfoPtr -> IO Bool
cArgInfoHasSRet a = toBool <$> ({#get CArgumentInfo->hasSRet#} a)
cArgInfoHasByVal :: ArgInfoPtr -> IO Bool
cArgInfoHasByVal a = toBool <$> ({#get CArgumentInfo->hasByVal#} a)
cArgInfoHasNest :: ArgInfoPtr -> IO Bool
cArgInfoHasNest a = toBool <$> ({#get CArgumentInfo->hasNest#} a)
cArgInfoHasNoAlias :: ArgInfoPtr -> IO Bool
cArgInfoHasNoAlias a = toBool <$> ({#get CArgumentInfo->hasNoAlias#} a)
cArgInfoHasNoCapture :: ArgInfoPtr -> IO Bool
cArgInfoHasNoCapture a = toBool <$> ({#get CArgumentInfo->hasNoCapture#} a)
data CBasicBlockInfo
{#pointer *CBasicBlockInfo as BasicBlockPtr -> CBasicBlockInfo #}
cBasicBlockInstructions :: BasicBlockPtr -> IO [ValuePtr]
cBasicBlockInstructions b =
peekArray b {#get CBasicBlockInfo->instructions#} {#get CBasicBlockInfo->blockLen#}
data CInlineAsmInfo
{#pointer *CInlineAsmInfo as InlineAsmInfoPtr -> CInlineAsmInfo #}
cInlineAsmString :: InlineAsmInfoPtr -> IO Text
cInlineAsmString a =
({#get CInlineAsmInfo->asmString#} a) >>= makeText
cInlineAsmConstraints :: InlineAsmInfoPtr -> IO Text
cInlineAsmConstraints a =
({#get CInlineAsmInfo->constraintString#} a) >>= makeText
data CBlockAddrInfo
{#pointer *CBlockAddrInfo as BlockAddrInfoPtr -> CBlockAddrInfo #}
cBlockAddrFunc :: BlockAddrInfoPtr -> IO ValuePtr
cBlockAddrFunc = {#get CBlockAddrInfo->func #}
cBlockAddrBlock :: BlockAddrInfoPtr -> IO ValuePtr
cBlockAddrBlock = {#get CBlockAddrInfo->block #}
data CAggregateInfo
{#pointer *CConstAggregate as AggregateInfoPtr -> CAggregateInfo #}
cAggregateValues :: AggregateInfoPtr -> IO [ValuePtr]
cAggregateValues a =
peekArray a {#get CConstAggregate->constants#} {#get CConstAggregate->numElements#}
data CConstFP
{#pointer *CConstFP as FPInfoPtr -> CConstFP #}
cFPVal :: FPInfoPtr -> IO Double
cFPVal f = realToFrac <$> ({#get CConstFP->val#} f)
data CConstInt
{#pointer *CConstInt as IntInfoPtr -> CConstInt #}
cIntVal :: IntInfoPtr -> IO Integer
cIntVal i = fromIntegral <$> ({#get CConstInt->val#} i)
cIntHugeVal :: IntInfoPtr -> IO (Maybe Integer)
cIntHugeVal i = do
s <- {#get CConstInt->hugeVal#} i
case s == nullPtr of
True -> return Nothing
False -> (Just . read) <$> peekCString s
data CInstructionInfo
{#pointer *CInstructionInfo as InstInfoPtr -> CInstructionInfo #}
cInstructionOperands :: InstInfoPtr -> IO [ValuePtr]
cInstructionOperands i =
peekArray i {#get CInstructionInfo->operands#} {#get CInstructionInfo->numOperands#}
cInstructionArithFlags :: InstInfoPtr -> IO ArithFlags
cInstructionArithFlags o = toEnum . fromIntegral <$> {#get CInstructionInfo->flags#} o
cInstructionAlign :: InstInfoPtr -> IO Int64
cInstructionAlign u = fromIntegral <$> {#get CInstructionInfo->align#} u
cInstructionIsVolatile :: InstInfoPtr -> IO Bool
cInstructionIsVolatile u = toBool <$> {#get CInstructionInfo->isVolatile#} u
cInstructionAddrSpace :: InstInfoPtr -> IO Int
cInstructionAddrSpace u = fromIntegral <$> {#get CInstructionInfo->addrSpace#} u
cInstructionCmpPred :: InstInfoPtr -> IO CmpPredicate
cInstructionCmpPred c = toEnum . fromIntegral <$> {#get CInstructionInfo->cmpPred#} c
cInstructionInBounds :: InstInfoPtr -> IO Bool
cInstructionInBounds g = toBool <$> {#get CInstructionInfo->inBounds#} g
cInstructionIndices :: InstInfoPtr -> IO [Int]
cInstructionIndices i =
peekArray i {#get CInstructionInfo->indices#} {#get CInstructionInfo->numIndices#}
data CConstExprInfo
{#pointer *CConstExprInfo as ConstExprPtr -> CConstExprInfo #}
cConstExprTag :: ConstExprPtr -> IO ValueTag
cConstExprTag e = toEnum . fromIntegral <$> {#get CConstExprInfo->instrType#} e
cConstExprInstInfo :: ConstExprPtr -> IO InstInfoPtr
cConstExprInstInfo = {#get CConstExprInfo->ii#}
data CPHIInfo
{#pointer *CPHIInfo as PHIInfoPtr -> CPHIInfo #}
cPHIValues :: PHIInfoPtr -> IO [ValuePtr]
cPHIValues p =
peekArray p {#get CPHIInfo->incomingValues#} {#get CPHIInfo->numIncomingValues#}
cPHIBlocks :: PHIInfoPtr -> IO [ValuePtr]
cPHIBlocks p =
peekArray p {#get CPHIInfo->valueBlocks#} {#get CPHIInfo->numIncomingValues#}
data CCallInfo
{#pointer *CCallInfo as CallInfoPtr -> CCallInfo #}
cCallValue :: CallInfoPtr -> IO ValuePtr
cCallValue = {#get CCallInfo->calledValue #}
cCallArguments :: CallInfoPtr -> IO [ValuePtr]
cCallArguments c =
peekArray c {#get CCallInfo->arguments#} {#get CCallInfo->argListLen#}
cCallConvention :: CallInfoPtr -> IO CallingConvention
cCallConvention c = toEnum . fromIntegral <$> {#get CCallInfo->callingConvention#} c
cCallHasSRet :: CallInfoPtr -> IO Bool
cCallHasSRet c = toBool <$> {#get CCallInfo->hasSRet#} c
cCallIsTail :: CallInfoPtr -> IO Bool
cCallIsTail c = toBool <$> {#get CCallInfo->isTail#} c
cCallUnwindDest :: CallInfoPtr -> IO ValuePtr
cCallUnwindDest = {#get CCallInfo->unwindDest#}
cCallNormalDest :: CallInfoPtr -> IO ValuePtr
cCallNormalDest = {#get CCallInfo->normalDest#}
data CAtomicInfo
{#pointer *CAtomicInfo as AtomicInfoPtr -> CAtomicInfo #}
cAtomicOrdering :: AtomicInfoPtr -> IO AtomicOrdering
cAtomicOrdering ai = toEnum . fromIntegral <$> {#get CAtomicInfo->ordering#} ai
cAtomicScope :: AtomicInfoPtr -> IO SynchronizationScope
cAtomicScope ai = toEnum . fromIntegral <$> {#get CAtomicInfo->scope#} ai
cAtomicOperation :: AtomicInfoPtr -> IO AtomicOperation
cAtomicOperation ai = toEnum . fromIntegral <$> {#get CAtomicInfo->operation#} ai
cAtomicIsVolatile :: AtomicInfoPtr -> IO Bool
cAtomicIsVolatile ai = toBool <$> {#get CAtomicInfo->isVolatile#} ai
cAtomicAddressSpace :: AtomicInfoPtr -> IO Int
cAtomicAddressSpace ai = fromIntegral <$> {#get CAtomicInfo->addrSpace#} ai
cAtomicPointerOperand :: AtomicInfoPtr -> IO ValuePtr
cAtomicPointerOperand = {#get CAtomicInfo->pointerOperand#}
cAtomicValueOperand :: AtomicInfoPtr -> IO ValuePtr
cAtomicValueOperand = {#get CAtomicInfo->valueOperand#}
cAtomicCompareOperand :: AtomicInfoPtr -> IO ValuePtr
cAtomicCompareOperand = {#get CAtomicInfo->compareOperand#}
data CLandingPadInfo
{#pointer *CLandingPadInfo as LandingPadInfoPtr -> CLandingPadInfo#}
cLandingPadPersonality :: LandingPadInfoPtr -> IO ValuePtr
cLandingPadPersonality = {#get CLandingPadInfo->personality#}
cLandingPadIsCleanup :: LandingPadInfoPtr -> IO Bool
cLandingPadIsCleanup li = toBool <$> {#get CLandingPadInfo->isCleanup#} li
cLandingPadClauses :: LandingPadInfoPtr -> IO [ValuePtr]
cLandingPadClauses li =
peekArray li {#get CLandingPadInfo->clauses #} {#get CLandingPadInfo->numClauses#}
cLandingPadClauseTypes :: LandingPadInfoPtr -> IO [LandingPadClause]
cLandingPadClauseTypes li = do
arr <- peekArray li {#get CLandingPadInfo->clauseTypes #} {#get CLandingPadInfo->numClauses#}
return $ map toEnum arr
-- | Parse the named file into an FFI-friendly representation of an
-- LLVM module.
{#fun marshalLLVM { id `Ptr CChar', `Int', fromBool `Bool' } -> `ModulePtr' id #}
{#fun marshalLLVMFile { `String', fromBool `Bool' } -> `ModulePtr' id #}
-- | Free all of the resources allocated by 'marshalLLVM'
{#fun disposeCModule { id `ModulePtr' } -> `()' #}
-- Helpers
-- This only seems to be necessary on i386 for some reason.
cIntConv :: (Integral a, Num b) => a -> b
cIntConv = fromIntegral