llvm-hs-pure (empty) → 4.0.0.0
raw patch · 32 files changed
+1870/−0 lines, 32 filesdep +basedep +containersdep +llvm-hs-puresetup-changed
Dependencies added: base, containers, llvm-hs-pure, mtl, parsec, semigroups, tasty, tasty-hunit, template-haskell, transformers, transformers-compat
Files
- LICENSE +30/−0
- Setup.hs +2/−0
- llvm-hs-pure.cabal +109/−0
- src/LLVM/AST.hs +63/−0
- src/LLVM/AST/AddrSpace.hs +8/−0
- src/LLVM/AST/Attribute.hs +17/−0
- src/LLVM/AST/COMDAT.hs +13/−0
- src/LLVM/AST/CallingConvention.hs +33/−0
- src/LLVM/AST/Constant.hs +237/−0
- src/LLVM/AST/DLL.hs +10/−0
- src/LLVM/AST/DataLayout.hs +76/−0
- src/LLVM/AST/Float.hs +20/−0
- src/LLVM/AST/FloatingPointPredicate.hs +27/−0
- src/LLVM/AST/FunctionAttribute.hs +52/−0
- src/LLVM/AST/Global.hs +134/−0
- src/LLVM/AST/InlineAssembly.hs +27/−0
- src/LLVM/AST/Instruction.hs +444/−0
- src/LLVM/AST/IntegerPredicate.hs +21/−0
- src/LLVM/AST/Linkage.hs +19/−0
- src/LLVM/AST/Name.hs +35/−0
- src/LLVM/AST/Operand.hs +40/−0
- src/LLVM/AST/ParameterAttribute.hs +27/−0
- src/LLVM/AST/RMWOperation.hs +22/−0
- src/LLVM/AST/ThreadLocalStorage.hs +12/−0
- src/LLVM/AST/Type.hs +99/−0
- src/LLVM/AST/Visibility.hs +8/−0
- src/LLVM/DataLayout.hs +123/−0
- src/LLVM/Prelude.hs +37/−0
- src/LLVM/TH.hs +32/−0
- test/LLVM/Test/DataLayout.hs +80/−0
- test/LLVM/Test/Tests.hs +9/−0
- test/Test.hs +4/−0
+ 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,2 @@+import Distribution.Simple+main = defaultMain
+ llvm-hs-pure.cabal view
@@ -0,0 +1,109 @@+name: llvm-hs-pure+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: Simple+stability: experimental+cabal-version: >= 1.8+category: Compilers/Interpreters, Code Generation+synopsis: Pure Haskell LLVM functionality (no FFI).+description:+ llvm-hs-pure is a set of pure Haskell types and functions for interacting with LLVM <http://llvm.org/>.+ It includes an ADT to represent LLVM IR (<http://llvm.org/docs/LangRef.html>). The llvm-hs package+ builds on this one with FFI bindings to LLVM, but llvm-hs-pure does not require LLVM to be available.+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 semigroups+ description: Add semigroups to build-depends for Data.List.NonEmpty. This will be selected automatically by cabal.+ default: False++library+ ghc-options: -Wall -fno-warn-name-shadowing+ if flag(semigroups)+ build-depends:+ base >= 4.7 && < 4.9,+ semigroups >= 0.18 && < 0.19+ else+ build-depends:+ base >= 4.9 && < 5+ build-depends:+ transformers >= 0.3 && < 0.6,+ transformers-compat >= 0.4,+ mtl >= 2.1,+ template-haskell >= 2.5.0.0,+ containers >= 0.4.2.1,+ parsec >= 3.1.3+ hs-source-dirs: src+ extensions:+ NoImplicitPrelude+ TupleSections+ DeriveDataTypeable+ EmptyDataDecls+ FlexibleContexts+ FlexibleInstances+ StandaloneDeriving+ ConstraintKinds+ exposed-modules:+ LLVM.AST+ LLVM.AST.AddrSpace+ LLVM.AST.InlineAssembly+ LLVM.AST.Attribute+ LLVM.AST.ParameterAttribute+ LLVM.AST.FunctionAttribute+ LLVM.AST.CallingConvention+ LLVM.AST.Constant+ LLVM.AST.DataLayout+ LLVM.AST.Float+ LLVM.AST.FloatingPointPredicate+ LLVM.AST.Global+ LLVM.AST.Instruction+ LLVM.AST.IntegerPredicate+ LLVM.AST.Linkage+ LLVM.AST.Name+ LLVM.AST.Operand+ LLVM.AST.RMWOperation+ LLVM.AST.ThreadLocalStorage+ LLVM.AST.Type+ LLVM.AST.Visibility+ LLVM.AST.DLL+ LLVM.AST.COMDAT+ LLVM.DataLayout+ LLVM.Prelude+ LLVM.TH++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:+ tasty >= 0.11,+ tasty-hunit >= 0.9,+ llvm-hs-pure,+ transformers >= 0.3,+ transformers-compat >= 0.4,+ containers >= 0.4.2.1,+ mtl >= 2.1+ hs-source-dirs: test+ extensions:+ TupleSections+ FlexibleInstances+ FlexibleContexts+ main-is: Test.hs+ other-modules:+ LLVM.Test.DataLayout+ LLVM.Test.Tests
+ src/LLVM/AST.hs view
@@ -0,0 +1,63 @@+-- | This module and descendants define AST data types to represent LLVM code.+-- Note that these types are designed for fidelity rather than convenience - if the truth+-- of what LLVM supports is less than pretty, so be it.+module LLVM.AST (+ Module(..), defaultModule,+ Definition(..),+ Global(GlobalVariable, GlobalAlias, Function),+ globalVariableDefaults,+ globalAliasDefaults,+ functionDefaults,+ UnnamedAddr(..),+ Parameter(..),+ BasicBlock(..),+ module LLVM.AST.Instruction,+ module LLVM.AST.Name,+ module LLVM.AST.Operand,+ module LLVM.AST.Type+ ) where++import LLVM.Prelude++import LLVM.AST.Name+import LLVM.AST.Type (Type(..), FloatingPointFormat(..))+import LLVM.AST.Global+import LLVM.AST.Operand+import LLVM.AST.Instruction+import LLVM.AST.DataLayout+import qualified LLVM.AST.Attribute as A+import qualified LLVM.AST.COMDAT as COMDAT++-- | Any thing which can be at the top level of a 'Module'+data Definition+ = GlobalDefinition Global+ | TypeDefinition Name (Maybe Type)+ | MetadataNodeDefinition MetadataNodeID [Maybe Metadata]+ | NamedMetadataDefinition String [MetadataNodeID]+ | ModuleInlineAssembly String+ | FunctionAttributes A.GroupID [A.FunctionAttribute]+ | COMDAT String COMDAT.SelectionKind+ deriving (Eq, Read, Show, Typeable, Data)++-- | <http://llvm.org/docs/LangRef.html#module-structure>+data Module =+ Module {+ moduleName :: String,+ moduleSourceFileName :: String,+ -- | a 'DataLayout', if specified, must match that of the eventual code generator+ moduleDataLayout :: Maybe DataLayout,+ moduleTargetTriple :: Maybe String,+ moduleDefinitions :: [Definition]+ }+ deriving (Eq, Read, Show, Typeable, Data)++-- | helper for making 'Module's+defaultModule :: Module+defaultModule =+ Module {+ moduleName = "<string>",+ moduleSourceFileName = "<string>",+ moduleDataLayout = Nothing,+ moduleTargetTriple = Nothing,+ moduleDefinitions = []+ }
+ src/LLVM/AST/AddrSpace.hs view
@@ -0,0 +1,8 @@+-- | Pointers exist in Address Spaces +module LLVM.AST.AddrSpace where++import LLVM.Prelude++-- | See <http://llvm.org/docs/LangRef.html#pointer-type>+data AddrSpace = AddrSpace Word32+ deriving (Eq, Ord, Read, Show, Typeable, Data)
+ src/LLVM/AST/Attribute.hs view
@@ -0,0 +1,17 @@+-- | Module to allow importing 'Attribute' distinctly qualified.+-- Before LLVM 3.5, the attributes which could be used on functions+-- and those which could be used on parameters were disjoint. In+-- LLVM 3.5, two attributes (readonly and readnone) can be used+-- in both contexts. Because their interpretation is different in+-- the two contexts and only those two attributes can be used in+-- both contexts, I've opted to keep the Haskell types for parameter+-- and function attributes distinct, but move the two types into+-- separate modules so they can have contructors with the same names.+module LLVM.AST.Attribute (+ ParameterAttribute(..),+ FunctionAttribute(..),+ GroupID(..)+ ) where++import LLVM.AST.ParameterAttribute hiding (ReadNone, ReadOnly, WriteOnly)+import LLVM.AST.FunctionAttribute
+ src/LLVM/AST/COMDAT.hs view
@@ -0,0 +1,13 @@+-- | Module to allow importing 'COMDAT.SelectionKind' distinctly qualified.+module LLVM.AST.COMDAT where++import LLVM.Prelude++-- | <http://llvm.org/docs/LangRef.html#comdats>+data SelectionKind+ = Any+ | ExactMatch+ | Largest+ | NoDuplicates+ | SameSize+ deriving (Eq, Read, Show, Typeable, Data)
+ src/LLVM/AST/CallingConvention.hs view
@@ -0,0 +1,33 @@+-- | Module to allow importing 'CallingConvention' distinctly qualified.+module LLVM.AST.CallingConvention where++import LLVM.Prelude++-- | <http://llvm.org/docs/LangRef.html#callingconv>+data CallingConvention+ = C+ | Fast+ | Cold+ | GHC+ | HiPE+ | WebKit_JS+ | AnyReg+ | PreserveMost+ | PreserveAll+ | X86_StdCall+ | X86_FastCall+ | ARM_APCS+ | ARM_AAPCS+ | ARM_AAPCS_VFP+ | MSP430_INTR+ | X86_ThisCall+ | PTX_Kernel+ | PTX_Device+ | SPIR_FUNC+ | SPIR_KERNEL+ | Intel_OCL_BI+ | X86_64_SysV+ | X86_64_Win64+ | Numbered Word32+ deriving (Eq, Read, Show, Typeable, Data)+
+ src/LLVM/AST/Constant.hs view
@@ -0,0 +1,237 @@+-- | A representation of LLVM constants+module LLVM.AST.Constant where++import LLVM.Prelude++import Data.Bits ((.|.), (.&.), complement, testBit, shiftL)++import LLVM.AST.Type+import LLVM.AST.Name+import LLVM.AST.FloatingPointPredicate (FloatingPointPredicate)+import LLVM.AST.IntegerPredicate (IntegerPredicate)+import qualified LLVM.AST.Float as F++{- |+<http://llvm.org/docs/LangRef.html#constants>++N.B. - <http://llvm.org/docs/LangRef.html#constant-expressions>++Although constant expressions and instructions have many similarites, there are important+differences - so they're represented using different types in this AST. At the cost of making it+harder to move an code back and forth between being constant and not, this approach embeds more of+the rules of what IR is legal into the Haskell types.+-}+data Constant+ = Int { integerBits :: Word32, integerValue :: Integer }+ | Float { floatValue :: F.SomeFloat }+ | Null { constantType :: Type }+ | Struct { structName :: Maybe Name, isPacked :: Bool, memberValues :: [ Constant ] }+ | Array { memberType :: Type, memberValues :: [ Constant ] }+ | Vector { memberValues :: [ Constant ] }+ | Undef { constantType :: Type }+ | BlockAddress { blockAddressFunction :: Name, blockAddressBlock :: Name }+ | GlobalReference Type Name+ | TokenNone+ | Add {+ nsw :: Bool,+ nuw :: Bool,+ operand0 :: Constant,+ operand1 :: Constant+ }+ | FAdd {+ operand0 :: Constant,+ operand1 :: Constant+ }+ | Sub {+ nsw :: Bool,+ nuw :: Bool,+ operand0 :: Constant,+ operand1 :: Constant+ }+ | FSub {+ operand0 :: Constant,+ operand1 :: Constant+ }+ | Mul {+ nsw :: Bool,+ nuw :: Bool,+ operand0 :: Constant,+ operand1 :: Constant+ }+ | FMul {+ operand0 :: Constant,+ operand1 :: Constant+ }+ | UDiv {+ exact :: Bool,+ operand0 :: Constant,+ operand1 :: Constant+ }+ | SDiv {+ exact :: Bool,+ operand0 :: Constant,+ operand1 :: Constant+ }+ | FDiv {+ operand0 :: Constant,+ operand1 :: Constant+ }+ | URem {+ operand0 :: Constant,+ operand1 :: Constant+ }+ | SRem {+ operand0 :: Constant,+ operand1 :: Constant+ }+ | FRem {+ operand0 :: Constant,+ operand1 :: Constant+ }+ | Shl {+ nsw :: Bool,+ nuw :: Bool,+ operand0 :: Constant,+ operand1 :: Constant+ }+ | LShr {+ exact :: Bool,+ operand0 :: Constant,+ operand1 :: Constant+ }+ | AShr {+ exact :: Bool,+ operand0 :: Constant,+ operand1 :: Constant+ }+ | And {+ operand0 :: Constant,+ operand1 :: Constant+ }+ | Or {+ operand0 :: Constant,+ operand1 :: Constant+ }+ | Xor {+ operand0 :: Constant,+ operand1 :: Constant+ }+ | GetElementPtr {+ inBounds :: Bool,+ address :: Constant,+ indices :: [Constant]+ }+ | Trunc {+ operand0 :: Constant,+ type' :: Type+ }+ | ZExt {+ operand0 :: Constant,+ type' :: Type+ }+ | SExt {+ operand0 :: Constant,+ type' :: Type+ }+ | FPToUI {+ operand0 :: Constant,+ type' :: Type+ }+ | FPToSI {+ operand0 :: Constant,+ type' :: Type+ }+ | UIToFP {+ operand0 :: Constant,+ type' :: Type+ }+ | SIToFP {+ operand0 :: Constant,+ type' :: Type+ }+ | FPTrunc {+ operand0 :: Constant,+ type' :: Type+ }+ | FPExt {+ operand0 :: Constant,+ type' :: Type+ }+ | PtrToInt {+ operand0 :: Constant,+ type' :: Type+ }+ | IntToPtr {+ operand0 :: Constant,+ type' :: Type+ }+ | BitCast {+ operand0 :: Constant,+ type' :: Type+ }+ | AddrSpaceCast {+ operand0 :: Constant,+ type' :: Type+ }+ | ICmp {+ iPredicate :: IntegerPredicate,+ operand0 :: Constant,+ operand1 :: Constant+ }+ | FCmp {+ fpPredicate :: FloatingPointPredicate,+ operand0 :: Constant,+ operand1 :: Constant+ }+ | Select {+ condition' :: Constant,+ trueValue :: Constant,+ falseValue :: Constant+ }+ | ExtractElement {+ vector :: Constant,+ index :: Constant+ }+ | InsertElement {+ vector :: Constant,+ element :: Constant,+ index :: Constant+ }+ | ShuffleVector {+ operand0 :: Constant,+ operand1 :: Constant,+ mask :: Constant+ }+ | ExtractValue {+ aggregate :: Constant,+ indices' :: [Word32]+ }+ | InsertValue {+ aggregate :: Constant,+ element :: Constant,+ indices' :: [Word32]+ }+ deriving (Eq, Ord, Read, Show, Typeable, Data)+++-- | Since LLVM types don't include signedness, there's ambiguity in interpreting+-- an constant as an Integer. The LLVM assembly printer prints integers as signed, but+-- cheats for 1-bit integers and prints them as 'true' or 'false'. That way it circuments the+-- otherwise awkward fact that a twos complement 1-bit number only has the values -1 and 0.+signedIntegerValue :: Constant -> Integer+signedIntegerValue (Int nBits' bits) =+ let nBits = fromIntegral nBits'+ in+ if bits `testBit` (nBits - 1) then bits .|. (-1 `shiftL` nBits) else bits+signedIntegerValue _ = error "signedIntegerValue is only defined for Int"++-- | This library's conversion from LLVM C++ objects will always produce integer constants+-- as unsigned, so this function in many cases is not necessary. However, nothing's to keep+-- stop direct construction of an 'Int' with a negative 'integerValue'. There's nothing in principle+-- wrong with such a value - it has perfectly good low order bits like any integer, and will be used+-- as such, likely producing the intended result if lowered to C++. If, however one wishes to interpret+-- an 'Int' of unknown provenance as unsigned, then this function will serve.+unsignedIntegerValue :: Constant -> Integer+unsignedIntegerValue (Int nBits bits) =+ bits .&. (complement (-1 `shiftL` (fromIntegral nBits)))+unsignedIntegerValue _ = error "unsignedIntegerValue is only defined for Int"
+ src/LLVM/AST/DLL.hs view
@@ -0,0 +1,10 @@+-- | Module to allow importing 'DLL.StorageClass' distinctly qualified.+module LLVM.AST.DLL where++import LLVM.Prelude++-- | <http://llvm.org/docs/LangRef.html#dll-storage-classes>+data StorageClass+ = Import+ | Export+ deriving (Eq, Read, Show, Typeable, Data)
+ src/LLVM/AST/DataLayout.hs view
@@ -0,0 +1,76 @@+-- | <http://llvm.org/docs/LangRef.html#data-layout>+module LLVM.AST.DataLayout where++import LLVM.Prelude++import Data.Map (Map)+import qualified Data.Map as Map+import Data.Set (Set)++import LLVM.AST.AddrSpace++-- | Little Endian is the one true way :-). Sadly, we must support the infidels.+data Endianness = LittleEndian | BigEndian+ deriving (Eq, Ord, Read, Show, Typeable, Data)++-- | An AlignmentInfo describes how a given type must and would best be aligned+data AlignmentInfo = AlignmentInfo {+ abiAlignment :: Word32,+ preferredAlignment :: Maybe Word32+ }+ deriving (Eq, Ord, Read, Show, Typeable, Data)++-- | A type of type for which 'AlignmentInfo' may be specified+data AlignType+ = IntegerAlign+ | VectorAlign+ | FloatAlign+ deriving (Eq, Ord, Read, Show, Typeable, Data)++-- | A style of name mangling+data Mangling+ = ELFMangling+ | MIPSMangling+ | MachOMangling+ | WindowsCOFFMangling+ deriving (Eq, Ord, Read, Show, Typeable, Data)++-- | a description of the various data layout properties which may be used during+-- optimization+data DataLayout = DataLayout {+ endianness :: Endianness,+ mangling :: Maybe Mangling,+ stackAlignment :: Maybe Word32,+ pointerLayouts :: Map AddrSpace (Word32, AlignmentInfo),+ typeLayouts :: Map (AlignType, Word32) AlignmentInfo,+ aggregateLayout :: AlignmentInfo,+ nativeSizes :: Maybe (Set Word32)+ }+ deriving (Eq, Ord, Read, Show, Typeable, Data)++-- | a default 'DataLayout'+defaultDataLayout :: Endianness -> DataLayout+defaultDataLayout endianness = DataLayout {+ endianness = endianness,+ mangling = Nothing,+ stackAlignment = Nothing,+ pointerLayouts = Map.fromList [+ (AddrSpace 0, (64, AlignmentInfo 64 (Just 64)))+ ],+ typeLayouts = Map.fromList [+ ((IntegerAlign, 1), AlignmentInfo 8 (Just 8)),+ ((IntegerAlign, 8), AlignmentInfo 8 (Just 8)),+ ((IntegerAlign, 16), AlignmentInfo 16 (Just 16)),+ ((IntegerAlign, 32), AlignmentInfo 32 (Just 32)),+ ((IntegerAlign, 64), AlignmentInfo 32 (Just 64)),+ ((FloatAlign, 16), AlignmentInfo 16 (Just 16)),+ ((FloatAlign, 32), AlignmentInfo 32 (Just 32)),+ ((FloatAlign, 64), AlignmentInfo 64 (Just 64)),+ ((FloatAlign, 128), AlignmentInfo 128 (Just 128)),+ ((VectorAlign, 64), AlignmentInfo 64 (Just 64)),+ ((VectorAlign, 128), AlignmentInfo 128 (Just 128))+ ],+ aggregateLayout = AlignmentInfo 0 (Just 64),+ nativeSizes = Nothing+ }+
+ src/LLVM/AST/Float.hs view
@@ -0,0 +1,20 @@+-- | This module provides a sub-namespace for a type to support the various sizes of floating point+-- numbers LLVM supports. It is most definitely intended to be imported qualified.+module LLVM.AST.Float where++import Prelude as P+import Data.Data+import Data.Word (Word16, Word64)++-- | A type summing up the various float types.+-- N.B. Note that in the constructors with multiple fields, the lower significance bits are on the right+-- - e.g. Quadruple highbits lowbits+data SomeFloat+ = Half Word16 + | Single Float+ | Double P.Double+ | Quadruple Word64 Word64+ | X86_FP80 Word16 Word64+ | PPC_FP128 Word64 Word64+ deriving (Eq, Ord, Read, Show, Typeable, Data)+
+ src/LLVM/AST/FloatingPointPredicate.hs view
@@ -0,0 +1,27 @@+-- | Predicates for the 'LLVM.AST.Instruction.FCmp' instruction+module LLVM.AST.FloatingPointPredicate where++import LLVM.Prelude++-- | <http://llvm.org/docs/LangRef.html#fcmp-instruction>+data FloatingPointPredicate+ = False+ | OEQ+ | OGT+ | OGE+ | OLT+ | OLE+ | ONE+ | ORD+ | UNO+ | UEQ+ | UGT+ | UGE+ | ULT+ | ULE+ | UNE+ | True+ deriving (Eq, Ord, Read, Show, Data, Typeable)+++
+ src/LLVM/AST/FunctionAttribute.hs view
@@ -0,0 +1,52 @@+-- | Module to allow importing 'FunctionAttribute' distinctly qualified.+module LLVM.AST.FunctionAttribute where++import LLVM.Prelude++-- | <http://llvm.org/docs/LangRef.html#function-attributes>+data FunctionAttribute+ = NoReturn+ | NoUnwind+ | ReadNone+ | ReadOnly+ | NoInline+ | NoRecurse+ | AlwaysInline+ | MinimizeSize+ | OptimizeForSize+ | OptimizeNone+ | StackProtect+ | StackProtectReq+ | StackProtectStrong+ | NoRedZone+ | NoImplicitFloat+ | Naked+ | InlineHint+ | StackAlignment Word64+ | ReturnsTwice+ | UWTable+ | NonLazyBind+ | Builtin+ | NoBuiltin+ | Cold+ | JumpTable+ | NoDuplicate+ | SanitizeAddress+ | SanitizeThread+ | SanitizeMemory+ | StringAttribute {+ stringAttributeKind :: String,+ stringAttributeValue :: String -- ^ Use "" for no value -- the two are conflated+ }+ | AllocSize Word (Maybe Word)+ | WriteOnly+ | ArgMemOnly+ | Convergent+ | InaccessibleMemOnly+ | InaccessibleMemOrArgMemOnly+ | SafeStack+ deriving (Eq, Ord, Read, Show, Typeable, Data)++-- | <http://llvm.org/docs/LangRef.html#attribute-groups>+newtype GroupID = GroupID Word+ deriving (Eq, Ord, Read, Show, Typeable, Data)
+ src/LLVM/AST/Global.hs view
@@ -0,0 +1,134 @@+-- | 'Global's - top-level values in 'Module's - and supporting structures.+module LLVM.AST.Global where++import LLVM.Prelude++import LLVM.AST.Name+import LLVM.AST.Type+import LLVM.AST.Constant (Constant)+import LLVM.AST.AddrSpace+import LLVM.AST.Instruction (Named, Instruction, Terminator)+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.ThreadLocalStorage as TLS+import qualified LLVM.AST.Attribute as A++-- | <http://llvm.org/doxygen/classllvm_1_1GlobalValue.html>+data Global+ -- | <http://llvm.org/docs/LangRef.html#global-variables>+ = GlobalVariable {+ name :: Name,+ linkage :: L.Linkage,+ visibility :: V.Visibility,+ dllStorageClass :: Maybe DLL.StorageClass,+ threadLocalMode :: Maybe TLS.Model,+ addrSpace :: AddrSpace,+ unnamedAddr :: Maybe UnnamedAddr,+ isConstant :: Bool,+ type' :: Type,+ initializer :: Maybe Constant,+ section :: Maybe String,+ comdat :: Maybe String,+ alignment :: Word32+ }+ -- | <http://llvm.org/docs/LangRef.html#aliases>+ | GlobalAlias {+ name :: Name,+ linkage :: L.Linkage,+ visibility :: V.Visibility,+ dllStorageClass :: Maybe DLL.StorageClass,+ threadLocalMode :: Maybe TLS.Model,+ unnamedAddr :: Maybe UnnamedAddr,+ type' :: Type,+ aliasee :: Constant+ }+ -- | <http://llvm.org/docs/LangRef.html#functions>+ | Function {+ linkage :: L.Linkage,+ visibility :: V.Visibility,+ dllStorageClass :: Maybe DLL.StorageClass,+ callingConvention :: CC.CallingConvention,+ returnAttributes :: [A.ParameterAttribute],+ returnType :: Type,+ name :: Name,+ parameters :: ([Parameter],Bool), -- ^ snd indicates varargs+ functionAttributes :: [Either A.GroupID A.FunctionAttribute],+ section :: Maybe String,+ comdat :: Maybe String,+ alignment :: Word32,+ garbageCollectorName :: Maybe String,+ prefix :: Maybe Constant,+ basicBlocks :: [BasicBlock],+ personalityFunction :: Maybe Constant+ }+ deriving (Eq, Read, Show, Typeable, Data)++-- | 'Parameter's for 'Function's+data Parameter = Parameter Type Name [A.ParameterAttribute]+ deriving (Eq, Read, Show, Typeable, Data)++-- | <http://llvm.org/doxygen/classllvm_1_1BasicBlock.html>+-- LLVM code in a function is a sequence of 'BasicBlock's each with a label,+-- some instructions, and a terminator.+data BasicBlock = BasicBlock Name [Named Instruction] (Named Terminator)+ deriving (Eq, Read, Show, Typeable, Data)++data UnnamedAddr = LocalAddr | GlobalAddr+ deriving (Eq, Read, Show, Typeable, Data)++-- | helper for making 'GlobalVariable's+globalVariableDefaults :: Global+globalVariableDefaults = + GlobalVariable {+ name = error "global variable name not defined",+ linkage = L.External,+ visibility = V.Default,+ dllStorageClass = Nothing,+ threadLocalMode = Nothing,+ addrSpace = AddrSpace 0,+ unnamedAddr = Nothing,+ isConstant = False,+ type' = error "global variable type not defined",+ initializer = Nothing,+ section = Nothing,+ comdat = Nothing,+ alignment = 0+ }++-- | helper for making 'GlobalAlias's+globalAliasDefaults :: Global+globalAliasDefaults =+ GlobalAlias {+ name = error "global alias name not defined",+ linkage = L.External,+ visibility = V.Default,+ dllStorageClass = Nothing,+ threadLocalMode = Nothing,+ unnamedAddr = Nothing,+ type' = error "global alias type not defined",+ aliasee = error "global alias aliasee not defined"+ }++-- | helper for making 'Function's+functionDefaults :: Global+functionDefaults = + Function {+ linkage = L.External,+ visibility = V.Default,+ dllStorageClass = Nothing,+ callingConvention = CC.C,+ returnAttributes = [],+ returnType = error "function return type not defined",+ name = error "function name not defined",+ parameters = ([], False),+ functionAttributes = [],+ section = Nothing,+ comdat = Nothing,+ alignment = 0,+ garbageCollectorName = Nothing,+ prefix = Nothing,+ basicBlocks = [],+ personalityFunction = Nothing+ }
+ src/LLVM/AST/InlineAssembly.hs view
@@ -0,0 +1,27 @@+-- | A representation of an LLVM inline assembly+module LLVM.AST.InlineAssembly where++import LLVM.Prelude++import LLVM.AST.Type++-- | the dialect of assembly used in an inline assembly string+-- <http://en.wikipedia.org/wiki/X86_assembly_language#Syntax>+data Dialect+ = ATTDialect+ | IntelDialect+ deriving (Eq, Read, Show, Typeable, Data)++-- | <http://llvm.org/docs/LangRef.html#inline-assembler-expressions>+-- to be used through 'LLVM.AST.Operand.CallableOperand' with a+-- 'LLVM.AST.Instruction.Call' instruction+data InlineAssembly+ = InlineAssembly {+ type' :: Type,+ assembly :: String,+ constraints :: String,+ hasSideEffects :: Bool,+ alignStack :: Bool,+ dialect :: Dialect+ }+ deriving (Eq, Read, Show, Typeable, Data)
+ src/LLVM/AST/Instruction.hs view
@@ -0,0 +1,444 @@+-- | LLVM instructions +-- <http://llvm.org/docs/LangRef.html#instruction-reference>+module LLVM.AST.Instruction where++import LLVM.Prelude++import LLVM.AST.Type+import LLVM.AST.Name+import LLVM.AST.Constant+import LLVM.AST.Operand+import LLVM.AST.IntegerPredicate (IntegerPredicate)+import LLVM.AST.FloatingPointPredicate (FloatingPointPredicate)+import LLVM.AST.RMWOperation (RMWOperation)+import LLVM.AST.CallingConvention (CallingConvention)+import qualified LLVM.AST.ParameterAttribute as PA (ParameterAttribute)+import qualified LLVM.AST.FunctionAttribute as FA (FunctionAttribute, GroupID)++import Data.List.NonEmpty++-- | <http://llvm.org/docs/LangRef.html#metadata-nodes-and-metadata-strings>+-- Metadata can be attached to an instruction+type InstructionMetadata = [(String, MetadataNode)]++-- | <http://llvm.org/docs/LangRef.html#terminators>+data Terminator + = Ret { + returnOperand :: Maybe Operand,+ metadata' :: InstructionMetadata+ }+ | CondBr { + condition :: Operand, + trueDest :: Name, + falseDest :: Name,+ metadata' :: InstructionMetadata+ }+ | Br { + dest :: Name,+ metadata' :: InstructionMetadata+ }+ | Switch {+ operand0' :: Operand,+ defaultDest :: Name,+ dests :: [(Constant, Name)],+ metadata' :: InstructionMetadata+ }+ | IndirectBr {+ operand0' :: Operand,+ possibleDests :: [Name],+ metadata' :: InstructionMetadata+ }+ | Invoke {+ callingConvention' :: CallingConvention,+ returnAttributes' :: [PA.ParameterAttribute],+ function' :: CallableOperand,+ arguments' :: [(Operand, [PA.ParameterAttribute])],+ functionAttributes' :: [Either FA.GroupID FA.FunctionAttribute],+ returnDest :: Name,+ exceptionDest :: Name,+ metadata' :: InstructionMetadata+ }+ | Resume {+ operand0' :: Operand,+ metadata' :: InstructionMetadata+ }+ | Unreachable {+ metadata' :: InstructionMetadata+ }+ | CleanupRet {+ cleanupPad :: Operand,+ unwindDest :: Maybe Name,+ metadata' :: InstructionMetadata+ }+ | CatchRet {+ catchPad :: Operand,+ successor :: Name,+ metadata' :: InstructionMetadata+ }+ | CatchSwitch {+ parentPad' :: Operand,+ catchHandlers :: NonEmpty Name,+ defaultUnwindDest :: Maybe Name,+ metadata' :: InstructionMetadata+ }+ deriving (Eq, Read, Show, Typeable, Data)++-- | <http://llvm.org/docs/LangRef.html#fast-math-flags>+data FastMathFlags + = NoFastMathFlags+ | UnsafeAlgebra+ | FastMathFlags {+ noNaNs :: Bool,+ noInfs :: Bool,+ noSignedZeros :: Bool,+ allowReciprocal :: Bool+ }+ deriving (Eq, Ord, Read, Show, Data, Typeable)++-- | <http://llvm.org/docs/LangRef.html#atomic-memory-ordering-constraints>+-- <http://llvm.org/docs/Atomics.html>+data MemoryOrdering+ = Unordered+ | Monotonic+ | Acquire+ | Release+ | AcquireRelease+ | SequentiallyConsistent+ deriving (Eq, Ord, Read, Show, Data, Typeable)++-- | <http://llvm.org/docs/LangRef.html#singlethread>+data SynchronizationScope+ = SingleThread+ | CrossThread+ deriving (Eq, Ord, Read, Show, Data, Typeable)++-- | An 'Atomicity' describes constraints on the visibility of effects of an atomic instruction+type Atomicity = (SynchronizationScope, MemoryOrdering)++-- | For the redoubtably complex 'LandingPad' instruction+data LandingPadClause+ = Catch Constant+ | Filter Constant+ deriving (Eq, Ord, Read, Show, Typeable, Data)++-- | For the call instruction+-- <http://llvm.org/docs/LangRef.html#call-instruction>+data TailCallKind = Tail | MustTail+ deriving (Eq, Ord, Read, Show, Typeable, Data)++-- | non-terminator instructions:+-- <http://llvm.org/docs/LangRef.html#binaryops>+-- <http://llvm.org/docs/LangRef.html#bitwiseops>+-- <http://llvm.org/docs/LangRef.html#memoryops>+-- <http://llvm.org/docs/LangRef.html#otherops>+data Instruction+ = Add { + nsw :: Bool,+ nuw :: Bool,+ operand0 :: Operand,+ operand1 :: Operand,+ metadata :: InstructionMetadata+ }+ | FAdd {+ fastMathFlags :: FastMathFlags,+ operand0 :: Operand,+ operand1 :: Operand,+ metadata :: InstructionMetadata+ }+ | Sub {+ nsw :: Bool,+ nuw :: Bool,+ operand0 :: Operand,+ operand1 :: Operand,+ metadata :: InstructionMetadata+ }+ | FSub { + fastMathFlags :: FastMathFlags,+ operand0 :: Operand, + operand1 :: Operand, + metadata :: InstructionMetadata+ }+ | Mul { + nsw :: Bool, + nuw :: Bool, + operand0 :: Operand, + operand1 :: Operand, + metadata :: InstructionMetadata + }+ | FMul { + fastMathFlags :: FastMathFlags,+ operand0 :: Operand, + operand1 :: Operand, + metadata :: InstructionMetadata+ }+ | UDiv { + exact :: Bool, + operand0 :: Operand, + operand1 :: Operand, + metadata :: InstructionMetadata+ }+ | SDiv { + exact :: Bool, + operand0 :: Operand, + operand1 :: Operand, + metadata :: InstructionMetadata+ }+ | FDiv { + fastMathFlags :: FastMathFlags,+ operand0 :: Operand, + operand1 :: Operand, + metadata :: InstructionMetadata+ }+ | URem { + operand0 :: Operand, + operand1 :: Operand, + metadata :: InstructionMetadata+ }+ | SRem { + operand0 :: Operand, + operand1 :: Operand, + metadata :: InstructionMetadata+ }+ | FRem { + fastMathFlags :: FastMathFlags,+ operand0 :: Operand, + operand1 :: Operand, + metadata :: InstructionMetadata+ }+ | Shl { + nsw :: Bool, + nuw :: Bool, + operand0 :: Operand, + operand1 :: Operand, + metadata :: InstructionMetadata+ }+ | LShr { + exact :: Bool, + operand0 :: Operand, + operand1 :: Operand, + metadata :: InstructionMetadata+ }+ | AShr { + exact :: Bool, + operand0 :: Operand, + operand1 :: Operand, + metadata :: InstructionMetadata+ }+ | And { + operand0 :: Operand, + operand1 :: Operand, + metadata :: InstructionMetadata+ }+ | Or { + operand0 :: Operand, + operand1 :: Operand, + metadata :: InstructionMetadata+ }+ | Xor { + operand0 :: Operand, + operand1 :: Operand, + metadata :: InstructionMetadata+ }+ | Alloca { + allocatedType :: Type,+ numElements :: Maybe Operand,+ alignment :: Word32,+ metadata :: InstructionMetadata+ }+ | Load {+ volatile :: Bool, + address :: Operand,+ maybeAtomicity :: Maybe Atomicity,+ alignment :: Word32,+ metadata :: InstructionMetadata+ }+ | Store {+ volatile :: Bool, + address :: Operand,+ value :: Operand,+ maybeAtomicity :: Maybe Atomicity,+ alignment :: Word32,+ metadata :: InstructionMetadata+ }+ | GetElementPtr { + inBounds :: Bool,+ address :: Operand,+ indices :: [Operand],+ metadata :: InstructionMetadata+ }+ | Fence { + atomicity :: Atomicity,+ metadata :: InstructionMetadata + }+ | CmpXchg { + volatile :: Bool,+ address :: Operand,+ expected :: Operand,+ replacement :: Operand,+ atomicity :: Atomicity,+ failureMemoryOrdering :: MemoryOrdering,+ metadata :: InstructionMetadata + }+ | AtomicRMW { + volatile :: Bool,+ rmwOperation :: RMWOperation,+ address :: Operand,+ value :: Operand,+ atomicity :: Atomicity,+ metadata :: InstructionMetadata + }+ | Trunc { + operand0 :: Operand,+ type' :: Type,+ metadata :: InstructionMetadata + }+ | ZExt {+ operand0 :: Operand,+ type' :: Type,+ metadata :: InstructionMetadata + }+ | SExt {+ operand0 :: Operand,+ type' :: Type,+ metadata :: InstructionMetadata+ }+ | FPToUI {+ operand0 :: Operand,+ type' :: Type,+ metadata :: InstructionMetadata+ }+ | FPToSI {+ operand0 :: Operand,+ type' :: Type,+ metadata :: InstructionMetadata+ }+ | UIToFP {+ operand0 :: Operand,+ type' :: Type,+ metadata :: InstructionMetadata+ }+ | SIToFP {+ operand0 :: Operand,+ type' :: Type,+ metadata :: InstructionMetadata+ }+ | FPTrunc {+ operand0 :: Operand,+ type' :: Type,+ metadata :: InstructionMetadata+ }+ | FPExt {+ operand0 :: Operand,+ type' :: Type,+ metadata :: InstructionMetadata+ }+ | PtrToInt {+ operand0 :: Operand,+ type' :: Type,+ metadata :: InstructionMetadata+ }+ | IntToPtr {+ operand0 :: Operand,+ type' :: Type,+ metadata :: InstructionMetadata+ }+ | BitCast {+ operand0 :: Operand,+ type' :: Type,+ metadata :: InstructionMetadata+ }+ | AddrSpaceCast {+ operand0 :: Operand,+ type' :: Type,+ metadata :: InstructionMetadata+ }+ | ICmp {+ iPredicate :: IntegerPredicate,+ operand0 :: Operand,+ operand1 :: Operand,+ metadata :: InstructionMetadata+ }+ | FCmp {+ fpPredicate :: FloatingPointPredicate,+ operand0 :: Operand,+ operand1 :: Operand,+ metadata :: InstructionMetadata+ }+ | Phi {+ type' :: Type,+ incomingValues :: [ (Operand, Name) ],+ metadata :: InstructionMetadata+ } + | Call {+ tailCallKind :: Maybe TailCallKind,+ callingConvention :: CallingConvention,+ returnAttributes :: [PA.ParameterAttribute],+ function :: CallableOperand,+ arguments :: [(Operand, [PA.ParameterAttribute])],+ functionAttributes :: [Either FA.GroupID FA.FunctionAttribute],+ metadata :: InstructionMetadata+ }+ | Select { + condition' :: Operand,+ trueValue :: Operand,+ falseValue :: Operand,+ metadata :: InstructionMetadata+ }+ | VAArg { + argList :: Operand,+ type' :: Type,+ metadata :: InstructionMetadata + }+ | ExtractElement { + vector :: Operand,+ index :: Operand,+ metadata :: InstructionMetadata + }+ | InsertElement { + vector :: Operand,+ element :: Operand,+ index :: Operand,+ metadata :: InstructionMetadata+ }+ | ShuffleVector { + operand0 :: Operand,+ operand1 :: Operand,+ mask :: Constant,+ metadata :: InstructionMetadata+ }+ | ExtractValue { + aggregate :: Operand,+ indices' :: [Word32],+ metadata :: InstructionMetadata+ }+ | InsertValue { + aggregate :: Operand,+ element :: Operand,+ indices' :: [Word32],+ metadata :: InstructionMetadata+ }+ | LandingPad { + type' :: Type,+ cleanup :: Bool,+ clauses :: [LandingPadClause],+ metadata :: InstructionMetadata + }+ | CatchPad {+ catchSwitch :: Operand,+ args :: [Operand],+ metadata :: InstructionMetadata+ }+ | CleanupPad {+ parentPad :: Operand,+ args :: [Operand],+ metadata :: InstructionMetadata+ }++ deriving (Eq, Read, Show, Typeable, Data)++-- | Instances of instructions may be given a name, allowing their results to be referenced as 'Operand's.+-- Sometimes instructions - e.g. a call to a function returning void - don't need names.+data Named a + = Name := a+ | Do a+ deriving (Eq, Read, Show, Typeable, Data)
+ src/LLVM/AST/IntegerPredicate.hs view
@@ -0,0 +1,21 @@+-- | Predicates for the 'LLVM.AST.Instruction.ICmp' instruction+module LLVM.AST.IntegerPredicate where++import LLVM.Prelude++-- | <http://llvm.org/docs/LangRef.html#icmp-instruction>+data IntegerPredicate+ = EQ+ | NE+ | UGT+ | UGE+ | ULT+ | ULE+ | SGT+ | SGE+ | SLT+ | SLE+ deriving (Eq, Ord, Read, Show, Data, Typeable)+++
+ src/LLVM/AST/Linkage.hs view
@@ -0,0 +1,19 @@+-- | Module to allow importing 'Linkage' distinctly qualified.+module LLVM.AST.Linkage where++import LLVM.Prelude++-- | <http://llvm.org/docs/LangRef.html#linkage>+data Linkage+ = Private+ | Internal+ | AvailableExternally+ | LinkOnce+ | Weak+ | Common+ | Appending+ | ExternWeak+ | LinkOnceODR+ | WeakODR+ | External+ deriving (Eq, Read, Show, Typeable, Data)
+ src/LLVM/AST/Name.hs view
@@ -0,0 +1,35 @@+-- | Names as used in LLVM IR+module LLVM.AST.Name where++import LLVM.Prelude+import Data.String++{- |+Objects of various sorts in LLVM IR are identified by address in the LLVM C++ API, and+may be given a string name. When printed to (resp. read from) human-readable LLVM assembly, objects without+string names are numbered sequentially (resp. must be numbered sequentially). String names may be quoted, and+are quoted when printed if they would otherwise be misread - e.g. when containing special characters.++> 7++means the seventh unnamed object, while++> "7"++means the object named with the string "7".++This libraries handling of 'UnName's during translation of the AST down into C++ IR is somewhat more+forgiving than the LLVM assembly parser: it does not require that unnamed values be numbered sequentially;+however, the numbers of 'UnName's passed into C++ cannot be preserved in the C++ objects. If the C++ IR is+printed as assembly or translated into a Haskell AST, unnamed nodes will be renumbered sequentially. Thus+unnamed node numbers should be thought of as having any scope limited to the 'LLVM.AST.Module' in+which they are used.+-}+data Name+ = Name String -- ^ a string name+ | UnName Word -- ^ a number for a nameless thing+ deriving (Eq, Ord, Read, Show, Typeable, Data)++instance IsString Name where+ fromString = Name+
+ src/LLVM/AST/Operand.hs view
@@ -0,0 +1,40 @@+-- | A type to represent operands to LLVM 'LLVM.AST.Instruction.Instruction's+module LLVM.AST.Operand where++import LLVM.Prelude++import LLVM.AST.Name+import LLVM.AST.Constant+import LLVM.AST.InlineAssembly+import LLVM.AST.Type++-- | A 'MetadataNodeID' is a number for identifying a metadata node.+-- Note this is different from "named metadata", which are represented with+-- 'LLVM.AST.NamedMetadataDefinition'.+newtype MetadataNodeID = MetadataNodeID Word+ deriving (Eq, Ord, Read, Show, Typeable, Data)++-- | <http://llvm.org/docs/LangRef.html#metadata>+data MetadataNode + = MetadataNode [Maybe Metadata]+ | MetadataNodeReference MetadataNodeID+ deriving (Eq, Ord, Read, Show, Typeable, Data)++-- | <http://llvm.org/docs/LangRef.html#metadata>+data Metadata+ = MDString String -- ^ <http://llvm.org/docs/doxygen/html/classllvm_1_1MDNode.html>+ | MDNode MetadataNode -- ^ <http://llvm.org/docs/doxygen/html/classllvm_1_1MDNode.html>+ | MDValue Operand -- ^ <http://llvm.org/docs/doxygen/html/classllvm_1_1ValueAsMetadata.html>+ deriving (Eq, Ord, Read, Show, Typeable, Data)++-- | An 'Operand' is roughly that which is an argument to an 'LLVM.AST.Instruction.Instruction'+data Operand + -- | %foo+ = LocalReference Type Name+ -- | 'Constant's include 'LLVM.AST.Constant.GlobalReference', for \@foo+ | ConstantOperand Constant+ | MetadataOperand Metadata+ deriving (Eq, Ord, Read, Show, Typeable, Data)++-- | The 'LLVM.AST.Instruction.Call' instruction is special: the callee can be inline assembly+type CallableOperand = Either InlineAssembly Operand
+ src/LLVM/AST/ParameterAttribute.hs view
@@ -0,0 +1,27 @@+-- | Module to allow importing 'ParameterAttribute' distinctly qualified.+module LLVM.AST.ParameterAttribute where++import LLVM.Prelude++-- | <http://llvm.org/docs/LangRef.html#parameter-attributes>+data ParameterAttribute+ = ZeroExt+ | SignExt+ | InReg+ | SRet+ | Alignment Word64+ | NoAlias+ | ByVal+ | NoCapture+ | Nest+ | ReadNone+ | ReadOnly+ | WriteOnly+ | InAlloca+ | NonNull+ | Dereferenceable Word64+ | DereferenceableOrNull Word64+ | Returned+ | SwiftSelf+ | SwiftError+ deriving (Eq, Ord, Read, Show, Typeable, Data)
+ src/LLVM/AST/RMWOperation.hs view
@@ -0,0 +1,22 @@+-- | Operations for the 'LLVM.AST.Instruction.AtomicRMW' instruction+module LLVM.AST.RMWOperation where++import LLVM.Prelude++-- | <http://llvm.org/docs/LangRef.html#atomicrmw-instruction>+data RMWOperation+ = Xchg+ | Add+ | Sub+ | And+ | Nand+ | Or+ | Xor+ | Max+ | Min+ | UMax+ | UMin+ deriving (Eq, Ord, Read, Show, Data, Typeable)+++
+ src/LLVM/AST/ThreadLocalStorage.hs view
@@ -0,0 +1,12 @@+-- | Module to allow importing 'ThreadLocalStorage.Model' distinctly qualified.+module LLVM.AST.ThreadLocalStorage where++import LLVM.Prelude++-- | <http://llvm.org/docs/LangRef.html#thread-local-storage-models>+data Model+ = GeneralDynamic+ | LocalDynamic+ | InitialExec+ | LocalExec+ deriving (Eq, Ord, Read, Show, Typeable, Data)
+ src/LLVM/AST/Type.hs view
@@ -0,0 +1,99 @@+-- | A representation of an LLVM type+module LLVM.AST.Type where++import LLVM.Prelude++import LLVM.AST.AddrSpace+import LLVM.AST.Name++-- | LLVM supports some special formats floating point format. This type is to distinguish those format.+-- I believe it's treated as a format for "a" float, as opposed to a vector of two floats, because+-- its intended usage is to represent a single number with a combined significand.+data FloatingPointFormat+ = IEEE+ | DoubleExtended+ | PairOfFloats+ deriving (Eq, Ord, Read, Show, Typeable, Data)++-- | <http://llvm.org/docs/LangRef.html#type-system>+data Type+ -- | <http://llvm.org/docs/LangRef.html#void-type>+ = VoidType+ -- | <http://llvm.org/docs/LangRef.html#integer-type>+ | IntegerType { typeBits :: Word32 }+ -- | <http://llvm.org/docs/LangRef.html#pointer-type>+ | PointerType { pointerReferent :: Type, pointerAddrSpace :: AddrSpace }+ -- | <http://llvm.org/docs/LangRef.html#floating-point-types>+ | FloatingPointType { typeBits :: Word32, floatingPointFormat :: FloatingPointFormat }+ -- | <http://llvm.org/docs/LangRef.html#function-type>+ | FunctionType { resultType :: Type, argumentTypes :: [Type], isVarArg :: Bool }+ -- | <http://llvm.org/docs/LangRef.html#vector-type>+ | VectorType { nVectorElements :: Word32, elementType :: Type }+ -- | <http://llvm.org/docs/LangRef.html#structure-type>+ | StructureType { isPacked :: Bool, elementTypes :: [Type] }+ -- | <http://llvm.org/docs/LangRef.html#array-type>+ | ArrayType { nArrayElements :: Word64, elementType :: Type }+ -- | <http://llvm.org/docs/LangRef.html#opaque-structure-types>+ | NamedTypeReference Name+ -- | <http://llvm.org/docs/LangRef.html#metadata-type>+ | MetadataType -- only to be used as a parameter type for a few intrinsics+ -- | <http://llvm.org/docs/LangRef.html#token-type>+ | TokenType+ deriving (Eq, Ord, Read, Show, Typeable, Data)++-- | An abbreviation for 'VoidType'+void :: Type+void = VoidType++-- | An abbreviation for 'IntegerType' 1+i1 :: Type+i1 = IntegerType 1++-- | An abbreviation for 'IntegerType' 8+i8 :: Type+i8 = IntegerType 8++-- | An abbreviation for 'IntegerType' 16+i16 :: Type+i16 = IntegerType 16++-- | An abbreviation for 'IntegerType' 32+i32 :: Type+i32 = IntegerType 32++-- | An abbreviation for 'IntegerType' 64+i64 :: Type+i64 = IntegerType 64++-- | An abbreviation for 'IntegerType' 128+i128 :: Type+i128 = IntegerType 128++-- | An abbreviation for 'PointerType' t ('AddrSpace' 0)+ptr :: Type -> Type+ptr t = PointerType t (AddrSpace 0)++-- | An abbreviation for 'FloatingPointType' 16 'IEEE'+half :: Type+half = FloatingPointType 16 IEEE++-- | An abbreviation for 'FloatingPointType' 32 'IEEE'+float :: Type+float = FloatingPointType 32 IEEE++-- | An abbreviation for 'FloatingPointType' 64 'IEEE'+double :: Type+double = FloatingPointType 64 IEEE++-- | An abbreviation for 'FloatingPointType' 128 'IEEE'+fp128 :: Type+fp128 = FloatingPointType 128 IEEE++-- | An abbreviation for 'FloatingPointType' 80 'DoubleExtended'+x86_fp80 :: Type+x86_fp80 = FloatingPointType 80 DoubleExtended++-- | An abbreviation for 'FloatingPointType' 128 'PairOfFloats'+ppc_fp128 :: Type+ppc_fp128 = FloatingPointType 128 PairOfFloats+
+ src/LLVM/AST/Visibility.hs view
@@ -0,0 +1,8 @@+-- | Module to allow importing 'Visibility' distinctly qualified.+module LLVM.AST.Visibility where++import LLVM.Prelude++-- | <http://llvm.org/docs/LangRef.html#visibility>+data Visibility = Default | Hidden | Protected+ deriving (Eq, Read, Show, Typeable, Data)
+ src/LLVM/DataLayout.hs view
@@ -0,0 +1,123 @@+module LLVM.DataLayout (+ dataLayoutToString,+ parseDataLayout+ ) where++import LLVM.Prelude++import Control.Monad.Trans.Except++import qualified Data.List as List+import qualified Data.Map as Map+import qualified Data.Set as Set++import Text.ParserCombinators.Parsec hiding (many)++import LLVM.AST.DataLayout+import LLVM.AST.AddrSpace++dataLayoutToString :: DataLayout -> String+dataLayoutToString dl =+ let sAlignmentInfo :: AlignmentInfo -> String+ sAlignmentInfo (AlignmentInfo abi pref) =+ show abi ++ case pref of+ Just pref | pref /= abi -> ":" ++ show pref+ _ -> ""+ sTriple :: (Word32, AlignmentInfo) -> String+ sTriple (s, ai) = show s ++ ":" ++ sAlignmentInfo ai+ atChar at = case at of+ IntegerAlign -> "i"+ VectorAlign -> "v"+ FloatAlign -> "f"+ manglingChar m = case m of+ ELFMangling -> "e"+ MIPSMangling -> "m"+ MachOMangling -> "o"+ WindowsCOFFMangling -> "w"+ oneOpt f accessor = maybe [] ((:[]) . f) (accessor dl)+ defDl = defaultDataLayout BigEndian+ nonDef :: Eq a => (DataLayout -> [a]) -> [a]+ nonDef f = (f dl) List.\\ (f defDl)+ in+ List.intercalate "-" (+ [case endianness dl of BigEndian -> "E"; LittleEndian -> "e"]+ +++ (oneOpt (("m:" ++) . manglingChar) mangling)+ +++ [+ "p" ++ (if a == 0 then "" else show a) ++ ":" ++ sTriple t+ | (AddrSpace a, t) <- nonDef (Map.toList . pointerLayouts)+ ] ++ [+ atChar at ++ sTriple (s, ai)+ | ((at, s), ai) <- nonDef (Map.toList . typeLayouts)+ ] ++ [+ "a:" ++ sAlignmentInfo ai | ai <- nonDef (pure . aggregateLayout)+ ] +++ (oneOpt (("n"++) . (List.intercalate ":") . (map show) . Set.toList) nativeSizes)+ +++ (oneOpt (("S"++) . show) stackAlignment)+ )++-- | Parse a 'DataLayout', given a default Endianness should one not be specified in the+-- string to be parsed. LLVM itself uses BigEndian as the default: thus pass BigEndian to+-- be conformant or LittleEndian to be righteously defiant.+parseDataLayout :: Endianness -> String -> Except String (Maybe DataLayout)+parseDataLayout _ "" = pure Nothing+parseDataLayout defaultEndianness s =+ let+ num :: Parser Word32+ num = read <$> many1 digit+ alignmentInfo :: Parser AlignmentInfo+ alignmentInfo = do+ abi <- num+ pref <- optionMaybe $ char ':' *> num+ pure $ AlignmentInfo abi pref+ triple :: Parser (Word32, AlignmentInfo)+ triple = do+ s <- num+ ai <- char ':' *> alignmentInfo+ pure (s, ai)+ parseSpec :: Parser (DataLayout -> DataLayout)+ parseSpec = choice [+ char 'e' *> pure (\dl -> dl { endianness = LittleEndian }),+ char 'E' *> pure (\dl -> dl { endianness = BigEndian }),+ do+ m <- char 'm' *> char ':' *> choice [+ char 'e' *> pure ELFMangling,+ char 'm' *> pure MIPSMangling,+ char 'o' *> pure MachOMangling,+ char 'w' *> pure WindowsCOFFMangling+ ]+ pure $ \dl -> dl { mangling = Just m },+ do+ n <- char 'S' *> num+ pure $ \dl -> dl { stackAlignment = Just n },+ do+ a <- char 'p' *> (AddrSpace <$> option 0 (read <$> many1 digit))+ t <- char ':' *> triple+ pure $ \dl -> dl { pointerLayouts = Map.insert a t (pointerLayouts dl) },+ do+ -- Ignore this obsolete approach to stack alignment. After the 3.4 release,+ -- this is never generated, still parsed but ignored. Comments suggest+ -- it will no longer be parsed after 4.0.+ void $ char 's' *> triple+ pure id,+ do+ at <- choice [+ char 'i' *> pure IntegerAlign,+ char 'v' *> pure VectorAlign,+ char 'f' *> pure FloatAlign+ ]+ (sz, ai) <- triple+ pure $ \dl -> dl { typeLayouts = Map.insert (at, sz) ai (typeLayouts dl) },+ do+ ai <- char 'a' *> char ':' *> alignmentInfo+ pure $ \dl -> dl { aggregateLayout = ai },+ do+ ns <- char 'n' *> num `sepBy` (char ':')+ pure $ \dl -> dl { nativeSizes = Just (Set.fromList ns) }+ ]+ in+ case parse (parseSpec `sepBy` (char '-')) "" s of+ Left _ -> throwE $ "ill formed data layout: " ++ show s+ Right fs -> pure . Just $ foldr ($) (defaultDataLayout defaultEndianness) fs
+ src/LLVM/Prelude.hs view
@@ -0,0 +1,37 @@+-- | This module is presents a prelude mostly like the post-Applicative-Monad world of+-- base >= 4.8 / ghc >= 7.10, even on earlier versions. It's intended as an internal library+-- for llvm-hs-pure and llvm-hs; it's exposed only to be shared between the two.+module LLVM.Prelude (+ module Prelude,+ module Data.Data,+ module Data.Int,+ module Data.Word,+ module Data.Functor,+ module Data.Foldable,+ module Data.Traversable,+ module Control.Applicative,+ module Control.Monad+ ) where++import Prelude hiding (+ mapM, mapM_,+ sequence, sequence_,+ concat,+ foldr, foldr1, foldl, foldl1,+ minimum, maximum, sum, product, all, any, and, or,+ concatMap,+ elem, notElem,+ )+import Data.Data hiding (typeOf)+import Data.Int+import Data.Word+import Data.Functor+import Data.Foldable+import Data.Traversable+import Control.Applicative+import Control.Monad hiding (+ forM, forM_,+ mapM, mapM_,+ sequence, sequence_,+ msum+ )
+ src/LLVM/TH.hs view
@@ -0,0 +1,32 @@+{-# LANGUAGE CPP #-}+-- | This module is presents template haskell mostly like the template-haskell >= 2.10 / ghc >= 7.10,+-- even on earlier versions. It's intended as an internal library for llvm-hs-pure and llvm-hs;+-- it's exposed only to be shared between the two.+module LLVM.TH (+ module Language.Haskell.TH,+ conT, appT+ ) where++#if __GLASGOW_HASKELL__ < 710+import LLVM.Prelude+#endif++import qualified Language.Haskell.TH as TH (conT, appT)+import Language.Haskell.TH hiding (conT, appT)++class Typish qt where+ appT :: qt -> Q Type -> qt+ conT :: Name -> qt++instance Typish (Q Type) where+ appT = TH.appT+ conT = TH.conT++#if __GLASGOW_HASKELL__ < 710+instance Typish (Q Pred) where+ appT qp qt = do+ ClassP n ts <- qp+ t <- qt+ return $ ClassP n (ts ++ [t])+ conT n = classP n []+#endif
+ test/LLVM/Test/DataLayout.hs view
@@ -0,0 +1,80 @@+module LLVM.Test.DataLayout where++import Test.Tasty+import Test.Tasty.HUnit++import Control.Monad.Trans.Except++import Data.Maybe+import qualified Data.Set as Set+import qualified Data.Map as Map++import LLVM.AST+import LLVM.AST.DataLayout+import LLVM.AST.AddrSpace+import LLVM.DataLayout++ddl = defaultDataLayout LittleEndian++tests = testGroup "DataLayout" [+ testCase name $ do+ let Right parsed = runExcept $ parseDataLayout LittleEndian strDl+ (dataLayoutToString astDl, parsed) @?= (strDl, Just astDl)+ | (name, astDl, strDl) <- [+ ("little-endian", ddl, "e"),+ ("big-endian", defaultDataLayout BigEndian, "E"),+ ("native", ddl { nativeSizes = Just (Set.fromList [8,32]) }, "e-n8:32"),+ (+ "no pref",+ ddl {+ pointerLayouts = + Map.singleton+ (AddrSpace 0) + (+ 8,+ AlignmentInfo {+ abiAlignment = 64,+ preferredAlignment = Nothing+ }+ )+ },+ "e-p:8:64"+ ), (+ "pref",+ ddl {+ pointerLayouts = + Map.insert (AddrSpace 1) (8, AlignmentInfo 32 (Just 64)) (pointerLayouts ddl)+ },+ "e-p1:8:32:64"+ ), (+ "def",+ ddl { pointerLayouts = Map.singleton (AddrSpace 0) (64, AlignmentInfo 64 (Just 64)) },+ "e"+ ), (+ "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"+ )+ ]+ ]
+ test/LLVM/Test/Tests.hs view
@@ -0,0 +1,9 @@+module LLVM.Test.Tests where++import Test.Tasty++import qualified LLVM.Test.DataLayout as DataLayout++tests = testGroup "llvm-hs" [+ DataLayout.tests+ ]
+ test/Test.hs view
@@ -0,0 +1,4 @@+import Test.Tasty as X+import qualified LLVM.Test.Tests as LLVM++main = defaultMain LLVM.tests