module DDC.Llvm.Pretty.Base ( Config(..) , Version , defaultConfig , configOfVersion , versionWantsMetadataAsValue , versionWantsLoadReturnTypes) where import Data.List import Data.Maybe ------------------------------------------------------------------------------- -- | LLVM pretty printer configuration. data Config = Config { configLlvmVersion :: Version , configWantsMetadataAsValue :: Bool , configWantsLoadReturnTypes :: Bool } deriving Show -- | LLVM version descriptor. type Version = String -- | Default config that can be used for debugging. defaultConfig :: Config defaultConfig = configOfVersion Nothing -- | Produce a default pretty printer config for the given version. -- -- Assume LLVM 3.8 as the default version unless told otherwise. -- This default should only be used during debugging, -- when compiling real modules the version will be set explicitly -- by the compilation driver. -- -- LLVM version 3.8.0 was current as of March 2016. -- configOfVersion :: Maybe Version -> Config configOfVersion mVersion = let version = fromMaybe "3.8.0" mVersion in Config { configLlvmVersion = version , configWantsMetadataAsValue = fromMaybe False $ versionWantsMetadataAsValue version , configWantsLoadReturnTypes = fromMaybe True $ versionWantsLoadReturnTypes version } -- | LLVM versions before 3.6.1 encoded meta data as a value, -- while after that it is typeless. versionWantsMetadataAsValue :: Version -> Maybe Bool versionWantsMetadataAsValue v | isPrefixOf "3.1." v = Just True | isPrefixOf "3.2." v = Just True | isPrefixOf "3.3." v = Just True | isPrefixOf "3.4." v = Just True | isPrefixOf "3.5." v = Just True | isPrefixOf "3." v = Just False | otherwise = Nothing -- | LLVM versions before 3.7.0 did not use a result type -- on load and getelembyptr operations, while after they -- did. versionWantsLoadReturnTypes :: Version -> Maybe Bool versionWantsLoadReturnTypes v | isPrefixOf "3.1." v = Just False | isPrefixOf "3.2." v = Just False | isPrefixOf "3.3." v = Just False | isPrefixOf "3.4." v = Just False | isPrefixOf "3.5." v = Just False | isPrefixOf "3.6." v = Just False | isPrefixOf "3." v = Just True | otherwise = Nothing