llvm-pretty 0.11.0 → 0.12.0.0
raw patch · 20 files changed
+3113/−415 lines, 20 filesdep +llvm-prettydep +sybdep +tastydep ~basedep ~prettydep ~template-haskellnew-uploaderPVP ok
version bump matches the API change (PVP)
Dependencies added: llvm-pretty, syb, tasty, tasty-hunit, text
Dependency ranges changed: base, pretty, template-haskell, th-abstraction
API changes (from Hackage documentation)
- Text.LLVM: instance Text.LLVM.IsValue GHC.Integer.Type.Integer
- Text.LLVM.AST: [dispVariables] :: DISubprogram' lab -> Maybe (ValMd' lab)
- Text.LLVM.AST: data DISubrange
- Text.LLVM.AST: instance Data.Data.Data Text.LLVM.AST.DISubrange
- Text.LLVM.AST: instance GHC.Classes.Eq Text.LLVM.AST.DISubrange
- Text.LLVM.AST: instance GHC.Classes.Ord Text.LLVM.AST.DISubrange
- Text.LLVM.AST: instance GHC.Generics.Generic Text.LLVM.AST.DISubrange
- Text.LLVM.AST: instance GHC.Show.Show Text.LLVM.AST.DISubrange
- Text.LLVM.Lens: dispVariablesLens :: forall lab_a86F. Lens' (DISubprogram' lab_a86F) (Maybe (ValMd' lab_a86F))
- Text.LLVM.PP: [cfgGEPImplicitType] :: Config -> Bool
- Text.LLVM.PP: [cfgLoadImplicitType] :: Config -> Bool
- Text.LLVM.PP: [cfgUseDILocation] :: Config -> Bool
- Text.LLVM.PP: checkConfig :: LLVM => (Config -> Bool) -> Bool
- Text.LLVM.PP: data Config
- Text.LLVM.PP: ppStructGlobalAttrs :: GlobalAttrs -> Doc
- Text.LLVM.PP: type LLVM = ?config :: Config
+ Text.LLVM: [funVisibility] :: FunAttrs -> Maybe Visibility
+ Text.LLVM: instance Text.LLVM.IsValue GHC.Num.Integer.Integer
+ Text.LLVM.AST: CallBr :: Type -> Value' lab -> [Typed (Value' lab)] -> lab -> [lab] -> Instr' lab
+ Text.LLVM.AST: ConstUnaryArith :: UnaryArithOp -> Typed (Value' lab) -> ConstExpr' lab
+ Text.LLVM.AST: DIArgList :: [ValMd' lab] -> DIArgList' lab
+ Text.LLVM.AST: DebugInfoArgList :: DIArgList' lab -> DebugInfo' lab
+ Text.LLVM.AST: DebugInfoAssignID :: DebugInfo' lab
+ Text.LLVM.AST: FNeg :: UnaryArithOp
+ Text.LLVM.AST: Freeze :: Typed (Value' lab) -> Instr' lab
+ Text.LLVM.AST: PtrOpaque :: Type' ident
+ Text.LLVM.AST: UnaryArith :: UnaryArithOp -> Typed (Value' lab) -> Instr' lab
+ Text.LLVM.AST: ValPoison :: Value' lab
+ Text.LLVM.AST: [aliasLinkage] :: GlobalAlias -> Maybe Linkage
+ Text.LLVM.AST: [aliasVisibility] :: GlobalAlias -> Maybe Visibility
+ Text.LLVM.AST: [decLinkage] :: Declare -> Maybe Linkage
+ Text.LLVM.AST: [decVisibility] :: Declare -> Maybe Visibility
+ Text.LLVM.AST: [defVisibility] :: Define -> Maybe Visibility
+ Text.LLVM.AST: [dialArgs] :: DIArgList' lab -> [ValMd' lab]
+ Text.LLVM.AST: [dictAllocated] :: DICompositeType' lab -> Maybe (ValMd' lab)
+ Text.LLVM.AST: [dictAnnotations] :: DICompositeType' lab -> Maybe (ValMd' lab)
+ Text.LLVM.AST: [dictAssociated] :: DICompositeType' lab -> Maybe (ValMd' lab)
+ Text.LLVM.AST: [dictDataLocation] :: DICompositeType' lab -> Maybe (ValMd' lab)
+ Text.LLVM.AST: [dictRank] :: DICompositeType' lab -> Maybe (ValMd' lab)
+ Text.LLVM.AST: [dicuDebugInfoForProf] :: DICompileUnit' lab -> Bool
+ Text.LLVM.AST: [dicuNameTableKind] :: DICompileUnit' lab -> Word64
+ Text.LLVM.AST: [dicuRangesBaseAddress] :: DICompileUnit' lab -> Bool
+ Text.LLVM.AST: [dicuSDK] :: DICompileUnit' lab -> Maybe String
+ Text.LLVM.AST: [dicuSysRoot] :: DICompileUnit' lab -> Maybe String
+ Text.LLVM.AST: [didtAnnotations] :: DIDerivedType' lab -> Maybe (ValMd' lab)
+ Text.LLVM.AST: [didtDwarfAddressSpace] :: DIDerivedType' lab -> Maybe Word32
+ Text.LLVM.AST: [digvAnnotations] :: DIGlobalVariable' lab -> Maybe (ValMd' lab)
+ Text.LLVM.AST: [dilvAlignment] :: DILocalVariable' lab -> Maybe Word32
+ Text.LLVM.AST: [dilvAnnotations] :: DILocalVariable' lab -> Maybe (ValMd' lab)
+ Text.LLVM.AST: [dispAnnotations] :: DISubprogram' lab -> Maybe (ValMd' lab)
+ Text.LLVM.AST: [dispRetainedNodes] :: DISubprogram' lab -> Maybe (ValMd' lab)
+ Text.LLVM.AST: [disrStride] :: DISubrange' lab -> Maybe (ValMd' lab)
+ Text.LLVM.AST: [disrUpperBound] :: DISubrange' lab -> Maybe (ValMd' lab)
+ Text.LLVM.AST: [dittpIsDefault] :: DITemplateTypeParameter' lab -> Maybe Bool
+ Text.LLVM.AST: [ditvpIsDefault] :: DITemplateValueParameter' lab -> Maybe Bool
+ Text.LLVM.AST: [modTriple] :: Module -> TargetTriple
+ Text.LLVM.AST: cmpTypeModuloOpaquePtrs :: Ord ident => Type' ident -> Type' ident -> Ordering
+ Text.LLVM.AST: data DISubrange' lab
+ Text.LLVM.AST: data UnaryArithOp
+ Text.LLVM.AST: eqTypeModuloOpaquePtrs :: Eq ident => Type' ident -> Type' ident -> Bool
+ Text.LLVM.AST: fixupOpaquePtrs :: Data a => a -> a
+ Text.LLVM.AST: instance Data.Data.Data Text.LLVM.AST.UnaryArithOp
+ Text.LLVM.AST: instance Data.Data.Data lab => Data.Data.Data (Text.LLVM.AST.DIArgList' lab)
+ Text.LLVM.AST: instance Data.Data.Data lab => Data.Data.Data (Text.LLVM.AST.DISubrange' lab)
+ Text.LLVM.AST: instance GHC.Base.Functor Text.LLVM.AST.DIArgList'
+ Text.LLVM.AST: instance GHC.Base.Functor Text.LLVM.AST.DISubrange'
+ Text.LLVM.AST: instance GHC.Classes.Eq Text.LLVM.AST.UnaryArithOp
+ Text.LLVM.AST: instance GHC.Classes.Eq ident => GHC.Classes.Eq (Text.LLVM.AST.TypeView' ident)
+ Text.LLVM.AST: instance GHC.Classes.Eq lab => GHC.Classes.Eq (Text.LLVM.AST.DIArgList' lab)
+ Text.LLVM.AST: instance GHC.Classes.Eq lab => GHC.Classes.Eq (Text.LLVM.AST.DISubrange' lab)
+ Text.LLVM.AST: instance GHC.Classes.Ord Text.LLVM.AST.UnaryArithOp
+ Text.LLVM.AST: instance GHC.Classes.Ord ident => GHC.Classes.Ord (Text.LLVM.AST.TypeView' ident)
+ Text.LLVM.AST: instance GHC.Classes.Ord lab => GHC.Classes.Ord (Text.LLVM.AST.DIArgList' lab)
+ Text.LLVM.AST: instance GHC.Classes.Ord lab => GHC.Classes.Ord (Text.LLVM.AST.DISubrange' lab)
+ Text.LLVM.AST: instance GHC.Generics.Generic (Text.LLVM.AST.DIArgList' lab)
+ Text.LLVM.AST: instance GHC.Generics.Generic (Text.LLVM.AST.DISubrange' lab)
+ Text.LLVM.AST: instance GHC.Generics.Generic Text.LLVM.AST.UnaryArithOp
+ Text.LLVM.AST: instance GHC.Generics.Generic1 Text.LLVM.AST.DIArgList'
+ Text.LLVM.AST: instance GHC.Generics.Generic1 Text.LLVM.AST.DISubrange'
+ Text.LLVM.AST: instance GHC.Show.Show Text.LLVM.AST.UnaryArithOp
+ Text.LLVM.AST: instance GHC.Show.Show lab => GHC.Show.Show (Text.LLVM.AST.DIArgList' lab)
+ Text.LLVM.AST: instance GHC.Show.Show lab => GHC.Show.Show (Text.LLVM.AST.DISubrange' lab)
+ Text.LLVM.AST: instance Language.Haskell.TH.Syntax.Lift Text.LLVM.AST.FloatType
+ Text.LLVM.AST: instance Language.Haskell.TH.Syntax.Lift Text.LLVM.AST.Ident
+ Text.LLVM.AST: instance Language.Haskell.TH.Syntax.Lift Text.LLVM.AST.PrimType
+ Text.LLVM.AST: instance Language.Haskell.TH.Syntax.Lift Text.LLVM.AST.Symbol
+ Text.LLVM.AST: newtype DIArgList' lab
+ Text.LLVM.AST: type DIArgList = DIArgList' BlockLabel
+ Text.LLVM.AST: type DISubrange = DISubrange' BlockLabel
+ Text.LLVM.DebugUtils: BitfieldInfo :: Word64 -> Word64 -> BitfieldInfo
+ Text.LLVM.DebugUtils: StructFieldInfo :: String -> Word64 -> Maybe BitfieldInfo -> Info -> StructFieldInfo
+ Text.LLVM.DebugUtils: Typedef :: String -> Info -> Info
+ Text.LLVM.DebugUtils: UnionFieldInfo :: String -> Info -> UnionFieldInfo
+ Text.LLVM.DebugUtils: [biBitfieldOffset] :: BitfieldInfo -> Word64
+ Text.LLVM.DebugUtils: [biFieldSize] :: BitfieldInfo -> Word64
+ Text.LLVM.DebugUtils: [sfiBitfield] :: StructFieldInfo -> Maybe BitfieldInfo
+ Text.LLVM.DebugUtils: [sfiInfo] :: StructFieldInfo -> Info
+ Text.LLVM.DebugUtils: [sfiName] :: StructFieldInfo -> String
+ Text.LLVM.DebugUtils: [sfiOffset] :: StructFieldInfo -> Word64
+ Text.LLVM.DebugUtils: [ufiInfo] :: UnionFieldInfo -> Info
+ Text.LLVM.DebugUtils: [ufiName] :: UnionFieldInfo -> String
+ Text.LLVM.DebugUtils: data BitfieldInfo
+ Text.LLVM.DebugUtils: data StructFieldInfo
+ Text.LLVM.DebugUtils: data UnionFieldInfo
+ Text.LLVM.DebugUtils: debugInfoArgNames :: Module -> Define -> IntMap String
+ Text.LLVM.DebugUtils: debugInfoDefineLines :: Module -> Map String Int
+ Text.LLVM.DebugUtils: debugInfoGlobalLines :: Module -> Map String Int
+ Text.LLVM.DebugUtils: guessTypeInfo :: IntMap ValMd -> String -> Info
+ Text.LLVM.DebugUtils: instance GHC.Show.Show Text.LLVM.DebugUtils.BitfieldInfo
+ Text.LLVM.DebugUtils: instance GHC.Show.Show Text.LLVM.DebugUtils.StructFieldInfo
+ Text.LLVM.DebugUtils: instance GHC.Show.Show Text.LLVM.DebugUtils.UnionFieldInfo
+ Text.LLVM.Labels: instance Text.LLVM.Labels.HasLabel Text.LLVM.AST.DIArgList'
+ Text.LLVM.Labels: instance Text.LLVM.Labels.HasLabel Text.LLVM.AST.DISubrange'
+ Text.LLVM.Lens: aliasLinkageLens :: Lens' GlobalAlias (Maybe Linkage)
+ Text.LLVM.Lens: aliasVisibilityLens :: Lens' GlobalAlias (Maybe Visibility)
+ Text.LLVM.Lens: decLinkageLens :: Lens' Declare (Maybe Linkage)
+ Text.LLVM.Lens: decVisibilityLens :: Lens' Declare (Maybe Visibility)
+ Text.LLVM.Lens: defVisibilityLens :: Lens' Define (Maybe Visibility)
+ Text.LLVM.Lens: dialArgsLens :: forall lab_i4avB lab_a4l91. Lens (DIArgList' lab_i4avB) (DIArgList' lab_a4l91) [ValMd' lab_i4avB] [ValMd' lab_a4l91]
+ Text.LLVM.Lens: dictAllocatedLens :: forall lab_i4ayD. Lens' (DICompositeType' lab_i4ayD) (Maybe (ValMd' lab_i4ayD))
+ Text.LLVM.Lens: dictAnnotationsLens :: forall lab_i4ayD. Lens' (DICompositeType' lab_i4ayD) (Maybe (ValMd' lab_i4ayD))
+ Text.LLVM.Lens: dictAssociatedLens :: forall lab_i4ayD. Lens' (DICompositeType' lab_i4ayD) (Maybe (ValMd' lab_i4ayD))
+ Text.LLVM.Lens: dictDataLocationLens :: forall lab_i4ayD. Lens' (DICompositeType' lab_i4ayD) (Maybe (ValMd' lab_i4ayD))
+ Text.LLVM.Lens: dictRankLens :: forall lab_i4ayD. Lens' (DICompositeType' lab_i4ayD) (Maybe (ValMd' lab_i4ayD))
+ Text.LLVM.Lens: dicuDebugInfoForProfLens :: forall lab_i4axB. Lens' (DICompileUnit' lab_i4axB) Bool
+ Text.LLVM.Lens: dicuNameTableKindLens :: forall lab_i4axB. Lens' (DICompileUnit' lab_i4axB) Word64
+ Text.LLVM.Lens: dicuRangesBaseAddressLens :: forall lab_i4axB. Lens' (DICompileUnit' lab_i4axB) Bool
+ Text.LLVM.Lens: dicuSDKLens :: forall lab_i4axB. Lens' (DICompileUnit' lab_i4axB) (Maybe String)
+ Text.LLVM.Lens: dicuSysRootLens :: forall lab_i4axB. Lens' (DICompileUnit' lab_i4axB) (Maybe String)
+ Text.LLVM.Lens: didtAnnotationsLens :: forall lab_i4aC6. Lens' (DIDerivedType' lab_i4aC6) (Maybe (ValMd' lab_i4aC6))
+ Text.LLVM.Lens: didtDwarfAddressSpaceLens :: forall lab_i4aC6. Lens' (DIDerivedType' lab_i4aC6) (Maybe Word32)
+ Text.LLVM.Lens: digvAnnotationsLens :: forall lab_i4aAU. Lens' (DIGlobalVariable' lab_i4aAU) (Maybe (ValMd' lab_i4aAU))
+ Text.LLVM.Lens: dilvAlignmentLens :: forall lab_i4aA9. Lens' (DILocalVariable' lab_i4aA9) (Maybe Word32)
+ Text.LLVM.Lens: dilvAnnotationsLens :: forall lab_i4aA9. Lens' (DILocalVariable' lab_i4aA9) (Maybe (ValMd' lab_i4aA9))
+ Text.LLVM.Lens: dispAnnotationsLens :: forall lab_i4azp. Lens' (DISubprogram' lab_i4azp) (Maybe (ValMd' lab_i4azp))
+ Text.LLVM.Lens: dispRetainedNodesLens :: forall lab_i4azp. Lens' (DISubprogram' lab_i4azp) (Maybe (ValMd' lab_i4azp))
+ Text.LLVM.Lens: disrStrideLens :: forall lab_i4aBr. Lens' (DISubrange' lab_i4aBr) (Maybe (ValMd' lab_i4aBr))
+ Text.LLVM.Lens: disrUpperBoundLens :: forall lab_i4aBr. Lens' (DISubrange' lab_i4aBr) (Maybe (ValMd' lab_i4aBr))
+ Text.LLVM.Lens: modTripleLens :: Lens' Module TargetTriple
+ Text.LLVM.PP: [cfgVer] :: Config -> LLVMVer
+ Text.LLVM.PP: class LLVMPretty a
+ Text.LLVM.PP: instance Text.LLVM.PP.LLVMPretty Text.LLVM.AST.Ident
+ Text.LLVM.PP: instance Text.LLVM.PP.LLVMPretty Text.LLVM.AST.Module
+ Text.LLVM.PP: instance Text.LLVM.PP.LLVMPretty Text.LLVM.AST.Symbol
+ Text.LLVM.PP: llvmPP :: LLVMPretty a => Fmt a
+ Text.LLVM.PP: llvmV3_5 :: LLVMVer
+ Text.LLVM.PP: llvmV3_6 :: LLVMVer
+ Text.LLVM.PP: llvmV3_7 :: LLVMVer
+ Text.LLVM.PP: llvmV3_8 :: LLVMVer
+ Text.LLVM.PP: llvmVer :: (?config :: Config) => LLVMVer
+ Text.LLVM.PP: llvmVlatest :: LLVMVer
+ Text.LLVM.PP: newtype Config
+ Text.LLVM.PP: ppCallBr :: Type -> Value -> [Typed Value] -> BlockLabel -> Fmt [BlockLabel]
+ Text.LLVM.PP: ppDIArgList :: Fmt DIArgList
+ Text.LLVM.PP: ppDIArgList' :: Fmt i -> Fmt (DIArgList' i)
+ Text.LLVM.PP: ppDISubrange' :: Fmt i -> Fmt (DISubrange' i)
+ Text.LLVM.PP: ppInt64ValMd' :: Bool -> Fmt i -> Fmt (ValMd' i)
+ Text.LLVM.PP: ppTargetTriple :: Fmt TargetTriple
+ Text.LLVM.PP: ppUnaryArithOp :: Fmt UnaryArithOp
+ Text.LLVM.PP: type LLVMVer = Int
+ Text.LLVM.PP: type Fmt a = (?config :: Config) => a -> Doc
+ Text.LLVM.PP: when' :: Monoid a => Bool -> a -> a
+ Text.LLVM.Triple.AST: AArch64 :: Arch
+ Text.LLVM.Triple.AST: AArch64SubArch_arm64e :: SubArch
+ Text.LLVM.Triple.AST: AArch64_32 :: Arch
+ Text.LLVM.Triple.AST: AArch64_BE :: Arch
+ Text.LLVM.Triple.AST: AIX :: OS
+ Text.LLVM.Triple.AST: AMD :: Vendor
+ Text.LLVM.Triple.AST: AMDGCN :: Arch
+ Text.LLVM.Triple.AST: AMDHSA :: OS
+ Text.LLVM.Triple.AST: AMDIL :: Arch
+ Text.LLVM.Triple.AST: AMDIL64 :: Arch
+ Text.LLVM.Triple.AST: AMDPAL :: OS
+ Text.LLVM.Triple.AST: ARC :: Arch
+ Text.LLVM.Triple.AST: ARM :: Arch
+ Text.LLVM.Triple.AST: ARMEB :: Arch
+ Text.LLVM.Triple.AST: ARMSubArch_v4t :: SubArch
+ Text.LLVM.Triple.AST: ARMSubArch_v5 :: SubArch
+ Text.LLVM.Triple.AST: ARMSubArch_v5te :: SubArch
+ Text.LLVM.Triple.AST: ARMSubArch_v6 :: SubArch
+ Text.LLVM.Triple.AST: ARMSubArch_v6k :: SubArch
+ Text.LLVM.Triple.AST: ARMSubArch_v6m :: SubArch
+ Text.LLVM.Triple.AST: ARMSubArch_v6t2 :: SubArch
+ Text.LLVM.Triple.AST: ARMSubArch_v7 :: SubArch
+ Text.LLVM.Triple.AST: ARMSubArch_v7em :: SubArch
+ Text.LLVM.Triple.AST: ARMSubArch_v7k :: SubArch
+ Text.LLVM.Triple.AST: ARMSubArch_v7m :: SubArch
+ Text.LLVM.Triple.AST: ARMSubArch_v7s :: SubArch
+ Text.LLVM.Triple.AST: ARMSubArch_v7ve :: SubArch
+ Text.LLVM.Triple.AST: ARMSubArch_v8 :: SubArch
+ Text.LLVM.Triple.AST: ARMSubArch_v8_1a :: SubArch
+ Text.LLVM.Triple.AST: ARMSubArch_v8_1m_mainline :: SubArch
+ Text.LLVM.Triple.AST: ARMSubArch_v8_2a :: SubArch
+ Text.LLVM.Triple.AST: ARMSubArch_v8_3a :: SubArch
+ Text.LLVM.Triple.AST: ARMSubArch_v8_4a :: SubArch
+ Text.LLVM.Triple.AST: ARMSubArch_v8_5a :: SubArch
+ Text.LLVM.Triple.AST: ARMSubArch_v8_6a :: SubArch
+ Text.LLVM.Triple.AST: ARMSubArch_v8_7a :: SubArch
+ Text.LLVM.Triple.AST: ARMSubArch_v8_8a :: SubArch
+ Text.LLVM.Triple.AST: ARMSubArch_v8m_baseline :: SubArch
+ Text.LLVM.Triple.AST: ARMSubArch_v8m_mainline :: SubArch
+ Text.LLVM.Triple.AST: ARMSubArch_v8r :: SubArch
+ Text.LLVM.Triple.AST: ARMSubArch_v9 :: SubArch
+ Text.LLVM.Triple.AST: ARMSubArch_v9_1a :: SubArch
+ Text.LLVM.Triple.AST: ARMSubArch_v9_2a :: SubArch
+ Text.LLVM.Triple.AST: ARMSubArch_v9_3a :: SubArch
+ Text.LLVM.Triple.AST: AVR :: Arch
+ Text.LLVM.Triple.AST: Amplification :: Environment
+ Text.LLVM.Triple.AST: Ananas :: OS
+ Text.LLVM.Triple.AST: Android :: Environment
+ Text.LLVM.Triple.AST: AnyHit :: Environment
+ Text.LLVM.Triple.AST: Apple :: Vendor
+ Text.LLVM.Triple.AST: BPFEB :: Arch
+ Text.LLVM.Triple.AST: BPFEL :: Arch
+ Text.LLVM.Triple.AST: CODE16 :: Environment
+ Text.LLVM.Triple.AST: COFF :: ObjectFormat
+ Text.LLVM.Triple.AST: CSKY :: Arch
+ Text.LLVM.Triple.AST: CSR :: Vendor
+ Text.LLVM.Triple.AST: CUDA :: OS
+ Text.LLVM.Triple.AST: Callable :: Environment
+ Text.LLVM.Triple.AST: ClosestHit :: Environment
+ Text.LLVM.Triple.AST: CloudABI :: OS
+ Text.LLVM.Triple.AST: Compute :: Environment
+ Text.LLVM.Triple.AST: Contiki :: OS
+ Text.LLVM.Triple.AST: CoreCLR :: Environment
+ Text.LLVM.Triple.AST: Cygnus :: Environment
+ Text.LLVM.Triple.AST: DXContainer :: ObjectFormat
+ Text.LLVM.Triple.AST: DXIL :: Arch
+ Text.LLVM.Triple.AST: Darwin :: OS
+ Text.LLVM.Triple.AST: Domain :: Environment
+ Text.LLVM.Triple.AST: DragonFly :: OS
+ Text.LLVM.Triple.AST: DriverKit :: OS
+ Text.LLVM.Triple.AST: EABI :: Environment
+ Text.LLVM.Triple.AST: EABIHF :: Environment
+ Text.LLVM.Triple.AST: ELF :: ObjectFormat
+ Text.LLVM.Triple.AST: ELFIAMCU :: OS
+ Text.LLVM.Triple.AST: Emscripten :: OS
+ Text.LLVM.Triple.AST: FreeBSD :: OS
+ Text.LLVM.Triple.AST: Freescale :: Vendor
+ Text.LLVM.Triple.AST: Fuchsia :: OS
+ Text.LLVM.Triple.AST: GNU :: Environment
+ Text.LLVM.Triple.AST: GNUABI64 :: Environment
+ Text.LLVM.Triple.AST: GNUABIN32 :: Environment
+ Text.LLVM.Triple.AST: GNUEABI :: Environment
+ Text.LLVM.Triple.AST: GNUEABIHF :: Environment
+ Text.LLVM.Triple.AST: GNUILP32 :: Environment
+ Text.LLVM.Triple.AST: GNUX32 :: Environment
+ Text.LLVM.Triple.AST: GOFF :: ObjectFormat
+ Text.LLVM.Triple.AST: Geometry :: Environment
+ Text.LLVM.Triple.AST: HSAIL :: Arch
+ Text.LLVM.Triple.AST: HSAIL64 :: Arch
+ Text.LLVM.Triple.AST: Haiku :: OS
+ Text.LLVM.Triple.AST: HermitCore :: OS
+ Text.LLVM.Triple.AST: Hexagon :: Arch
+ Text.LLVM.Triple.AST: Hull :: Environment
+ Text.LLVM.Triple.AST: Hurd :: OS
+ Text.LLVM.Triple.AST: IBM :: Vendor
+ Text.LLVM.Triple.AST: IOS :: OS
+ Text.LLVM.Triple.AST: ImaginationTechnologies :: Vendor
+ Text.LLVM.Triple.AST: Intersection :: Environment
+ Text.LLVM.Triple.AST: Itanium :: Environment
+ Text.LLVM.Triple.AST: KFreeBSD :: OS
+ Text.LLVM.Triple.AST: Kalimba :: Arch
+ Text.LLVM.Triple.AST: KalimbaSubArch_v3 :: SubArch
+ Text.LLVM.Triple.AST: KalimbaSubArch_v4 :: SubArch
+ Text.LLVM.Triple.AST: KalimbaSubArch_v5 :: SubArch
+ Text.LLVM.Triple.AST: Lanai :: Arch
+ Text.LLVM.Triple.AST: Le32 :: Arch
+ Text.LLVM.Triple.AST: Le64 :: Arch
+ Text.LLVM.Triple.AST: Library :: Environment
+ Text.LLVM.Triple.AST: Linux :: OS
+ Text.LLVM.Triple.AST: LoongArch32 :: Arch
+ Text.LLVM.Triple.AST: LoongArch64 :: Arch
+ Text.LLVM.Triple.AST: Lv2 :: OS
+ Text.LLVM.Triple.AST: M68k :: Arch
+ Text.LLVM.Triple.AST: MIPS :: Arch
+ Text.LLVM.Triple.AST: MIPS64 :: Arch
+ Text.LLVM.Triple.AST: MIPS64EL :: Arch
+ Text.LLVM.Triple.AST: MIPSEL :: Arch
+ Text.LLVM.Triple.AST: MSP430 :: Arch
+ Text.LLVM.Triple.AST: MSVC :: Environment
+ Text.LLVM.Triple.AST: MacABI :: Environment
+ Text.LLVM.Triple.AST: MacOSX :: OS
+ Text.LLVM.Triple.AST: MachO :: ObjectFormat
+ Text.LLVM.Triple.AST: Mesa :: Vendor
+ Text.LLVM.Triple.AST: Mesa3D :: OS
+ Text.LLVM.Triple.AST: Mesh :: Environment
+ Text.LLVM.Triple.AST: Minix :: OS
+ Text.LLVM.Triple.AST: MipsSubArch_r6 :: SubArch
+ Text.LLVM.Triple.AST: MipsTechnologies :: Vendor
+ Text.LLVM.Triple.AST: Miss :: Environment
+ Text.LLVM.Triple.AST: Musl :: Environment
+ Text.LLVM.Triple.AST: MuslEABI :: Environment
+ Text.LLVM.Triple.AST: MuslEABIHF :: Environment
+ Text.LLVM.Triple.AST: MuslX32 :: Environment
+ Text.LLVM.Triple.AST: Myriad :: Vendor
+ Text.LLVM.Triple.AST: NVCL :: OS
+ Text.LLVM.Triple.AST: NVIDIA :: Vendor
+ Text.LLVM.Triple.AST: NVPTX :: Arch
+ Text.LLVM.Triple.AST: NVPTX64 :: Arch
+ Text.LLVM.Triple.AST: NaCl :: OS
+ Text.LLVM.Triple.AST: NetBSD :: OS
+ Text.LLVM.Triple.AST: NoSubArch :: SubArch
+ Text.LLVM.Triple.AST: OpenBSD :: OS
+ Text.LLVM.Triple.AST: OpenEmbedded :: Vendor
+ Text.LLVM.Triple.AST: PC :: Vendor
+ Text.LLVM.Triple.AST: PPC :: Arch
+ Text.LLVM.Triple.AST: PPC64 :: Arch
+ Text.LLVM.Triple.AST: PPC64LE :: Arch
+ Text.LLVM.Triple.AST: PPCLE :: Arch
+ Text.LLVM.Triple.AST: PPCSubArch_spe :: SubArch
+ Text.LLVM.Triple.AST: PS4 :: OS
+ Text.LLVM.Triple.AST: PS5 :: OS
+ Text.LLVM.Triple.AST: Pixel :: Environment
+ Text.LLVM.Triple.AST: R600 :: Arch
+ Text.LLVM.Triple.AST: RISCV32 :: Arch
+ Text.LLVM.Triple.AST: RISCV64 :: Arch
+ Text.LLVM.Triple.AST: RTEMS :: OS
+ Text.LLVM.Triple.AST: RayGeneration :: Environment
+ Text.LLVM.Triple.AST: RenderScript32 :: Arch
+ Text.LLVM.Triple.AST: RenderScript64 :: Arch
+ Text.LLVM.Triple.AST: SCEI :: Vendor
+ Text.LLVM.Triple.AST: SHAVE :: Arch
+ Text.LLVM.Triple.AST: SPIR :: Arch
+ Text.LLVM.Triple.AST: SPIR64 :: Arch
+ Text.LLVM.Triple.AST: SPIRV :: ObjectFormat
+ Text.LLVM.Triple.AST: SPIRV32 :: Arch
+ Text.LLVM.Triple.AST: SPIRV64 :: Arch
+ Text.LLVM.Triple.AST: SPIRVSubArch_v10 :: SubArch
+ Text.LLVM.Triple.AST: SPIRVSubArch_v11 :: SubArch
+ Text.LLVM.Triple.AST: SPIRVSubArch_v12 :: SubArch
+ Text.LLVM.Triple.AST: SPIRVSubArch_v13 :: SubArch
+ Text.LLVM.Triple.AST: SPIRVSubArch_v14 :: SubArch
+ Text.LLVM.Triple.AST: SPIRVSubArch_v15 :: SubArch
+ Text.LLVM.Triple.AST: SUSE :: Vendor
+ Text.LLVM.Triple.AST: ShaderModel :: OS
+ Text.LLVM.Triple.AST: Simulator :: Environment
+ Text.LLVM.Triple.AST: Solaris :: OS
+ Text.LLVM.Triple.AST: Sparc :: Arch
+ Text.LLVM.Triple.AST: SparcEL :: Arch
+ Text.LLVM.Triple.AST: Sparcv9 :: Arch
+ Text.LLVM.Triple.AST: SystemZ :: Arch
+ Text.LLVM.Triple.AST: TCE :: Arch
+ Text.LLVM.Triple.AST: TCELE :: Arch
+ Text.LLVM.Triple.AST: TargetTriple :: Arch -> SubArch -> Vendor -> OS -> Environment -> ObjectFormat -> TargetTriple
+ Text.LLVM.Triple.AST: Thumb :: Arch
+ Text.LLVM.Triple.AST: ThumbEB :: Arch
+ Text.LLVM.Triple.AST: TvOS :: OS
+ Text.LLVM.Triple.AST: UnknownArch :: Arch
+ Text.LLVM.Triple.AST: UnknownEnvironment :: Environment
+ Text.LLVM.Triple.AST: UnknownOS :: OS
+ Text.LLVM.Triple.AST: UnknownObjectFormat :: ObjectFormat
+ Text.LLVM.Triple.AST: UnknownVendor :: Vendor
+ Text.LLVM.Triple.AST: VE :: Arch
+ Text.LLVM.Triple.AST: Vertex :: Environment
+ Text.LLVM.Triple.AST: WASI :: OS
+ Text.LLVM.Triple.AST: Wasm :: ObjectFormat
+ Text.LLVM.Triple.AST: Wasm32 :: Arch
+ Text.LLVM.Triple.AST: Wasm64 :: Arch
+ Text.LLVM.Triple.AST: WatchOS :: OS
+ Text.LLVM.Triple.AST: Win32 :: OS
+ Text.LLVM.Triple.AST: X86 :: Arch
+ Text.LLVM.Triple.AST: X86_64 :: Arch
+ Text.LLVM.Triple.AST: XCOFF :: ObjectFormat
+ Text.LLVM.Triple.AST: XCore :: Arch
+ Text.LLVM.Triple.AST: ZOS :: OS
+ Text.LLVM.Triple.AST: [ttArch] :: TargetTriple -> Arch
+ Text.LLVM.Triple.AST: [ttEnv] :: TargetTriple -> Environment
+ Text.LLVM.Triple.AST: [ttOS] :: TargetTriple -> OS
+ Text.LLVM.Triple.AST: [ttObjFmt] :: TargetTriple -> ObjectFormat
+ Text.LLVM.Triple.AST: [ttSubArch] :: TargetTriple -> SubArch
+ Text.LLVM.Triple.AST: [ttVendor] :: TargetTriple -> Vendor
+ Text.LLVM.Triple.AST: data Arch
+ Text.LLVM.Triple.AST: data Environment
+ Text.LLVM.Triple.AST: data OS
+ Text.LLVM.Triple.AST: data ObjectFormat
+ Text.LLVM.Triple.AST: data SubArch
+ Text.LLVM.Triple.AST: data TargetTriple
+ Text.LLVM.Triple.AST: data Vendor
+ Text.LLVM.Triple.AST: instance Data.Data.Data Text.LLVM.Triple.AST.Arch
+ Text.LLVM.Triple.AST: instance Data.Data.Data Text.LLVM.Triple.AST.Environment
+ Text.LLVM.Triple.AST: instance Data.Data.Data Text.LLVM.Triple.AST.OS
+ Text.LLVM.Triple.AST: instance Data.Data.Data Text.LLVM.Triple.AST.ObjectFormat
+ Text.LLVM.Triple.AST: instance Data.Data.Data Text.LLVM.Triple.AST.SubArch
+ Text.LLVM.Triple.AST: instance Data.Data.Data Text.LLVM.Triple.AST.TargetTriple
+ Text.LLVM.Triple.AST: instance Data.Data.Data Text.LLVM.Triple.AST.Vendor
+ Text.LLVM.Triple.AST: instance GHC.Base.Monoid Text.LLVM.Triple.AST.Arch
+ Text.LLVM.Triple.AST: instance GHC.Base.Monoid Text.LLVM.Triple.AST.Environment
+ Text.LLVM.Triple.AST: instance GHC.Base.Monoid Text.LLVM.Triple.AST.OS
+ Text.LLVM.Triple.AST: instance GHC.Base.Monoid Text.LLVM.Triple.AST.ObjectFormat
+ Text.LLVM.Triple.AST: instance GHC.Base.Monoid Text.LLVM.Triple.AST.SubArch
+ Text.LLVM.Triple.AST: instance GHC.Base.Monoid Text.LLVM.Triple.AST.TargetTriple
+ Text.LLVM.Triple.AST: instance GHC.Base.Monoid Text.LLVM.Triple.AST.Vendor
+ Text.LLVM.Triple.AST: instance GHC.Base.Semigroup Text.LLVM.Triple.AST.Arch
+ Text.LLVM.Triple.AST: instance GHC.Base.Semigroup Text.LLVM.Triple.AST.Environment
+ Text.LLVM.Triple.AST: instance GHC.Base.Semigroup Text.LLVM.Triple.AST.OS
+ Text.LLVM.Triple.AST: instance GHC.Base.Semigroup Text.LLVM.Triple.AST.ObjectFormat
+ Text.LLVM.Triple.AST: instance GHC.Base.Semigroup Text.LLVM.Triple.AST.SubArch
+ Text.LLVM.Triple.AST: instance GHC.Base.Semigroup Text.LLVM.Triple.AST.TargetTriple
+ Text.LLVM.Triple.AST: instance GHC.Base.Semigroup Text.LLVM.Triple.AST.Vendor
+ Text.LLVM.Triple.AST: instance GHC.Classes.Eq Text.LLVM.Triple.AST.Arch
+ Text.LLVM.Triple.AST: instance GHC.Classes.Eq Text.LLVM.Triple.AST.Environment
+ Text.LLVM.Triple.AST: instance GHC.Classes.Eq Text.LLVM.Triple.AST.OS
+ Text.LLVM.Triple.AST: instance GHC.Classes.Eq Text.LLVM.Triple.AST.ObjectFormat
+ Text.LLVM.Triple.AST: instance GHC.Classes.Eq Text.LLVM.Triple.AST.SubArch
+ Text.LLVM.Triple.AST: instance GHC.Classes.Eq Text.LLVM.Triple.AST.TargetTriple
+ Text.LLVM.Triple.AST: instance GHC.Classes.Eq Text.LLVM.Triple.AST.Vendor
+ Text.LLVM.Triple.AST: instance GHC.Classes.Ord Text.LLVM.Triple.AST.Arch
+ Text.LLVM.Triple.AST: instance GHC.Classes.Ord Text.LLVM.Triple.AST.Environment
+ Text.LLVM.Triple.AST: instance GHC.Classes.Ord Text.LLVM.Triple.AST.OS
+ Text.LLVM.Triple.AST: instance GHC.Classes.Ord Text.LLVM.Triple.AST.ObjectFormat
+ Text.LLVM.Triple.AST: instance GHC.Classes.Ord Text.LLVM.Triple.AST.SubArch
+ Text.LLVM.Triple.AST: instance GHC.Classes.Ord Text.LLVM.Triple.AST.TargetTriple
+ Text.LLVM.Triple.AST: instance GHC.Classes.Ord Text.LLVM.Triple.AST.Vendor
+ Text.LLVM.Triple.AST: instance GHC.Enum.Bounded Text.LLVM.Triple.AST.Arch
+ Text.LLVM.Triple.AST: instance GHC.Enum.Bounded Text.LLVM.Triple.AST.Environment
+ Text.LLVM.Triple.AST: instance GHC.Enum.Bounded Text.LLVM.Triple.AST.OS
+ Text.LLVM.Triple.AST: instance GHC.Enum.Bounded Text.LLVM.Triple.AST.ObjectFormat
+ Text.LLVM.Triple.AST: instance GHC.Enum.Bounded Text.LLVM.Triple.AST.SubArch
+ Text.LLVM.Triple.AST: instance GHC.Enum.Bounded Text.LLVM.Triple.AST.TargetTriple
+ Text.LLVM.Triple.AST: instance GHC.Enum.Bounded Text.LLVM.Triple.AST.Vendor
+ Text.LLVM.Triple.AST: instance GHC.Enum.Enum Text.LLVM.Triple.AST.Arch
+ Text.LLVM.Triple.AST: instance GHC.Enum.Enum Text.LLVM.Triple.AST.Environment
+ Text.LLVM.Triple.AST: instance GHC.Enum.Enum Text.LLVM.Triple.AST.OS
+ Text.LLVM.Triple.AST: instance GHC.Enum.Enum Text.LLVM.Triple.AST.ObjectFormat
+ Text.LLVM.Triple.AST: instance GHC.Enum.Enum Text.LLVM.Triple.AST.SubArch
+ Text.LLVM.Triple.AST: instance GHC.Enum.Enum Text.LLVM.Triple.AST.Vendor
+ Text.LLVM.Triple.AST: instance GHC.Generics.Generic Text.LLVM.Triple.AST.Arch
+ Text.LLVM.Triple.AST: instance GHC.Generics.Generic Text.LLVM.Triple.AST.Environment
+ Text.LLVM.Triple.AST: instance GHC.Generics.Generic Text.LLVM.Triple.AST.OS
+ Text.LLVM.Triple.AST: instance GHC.Generics.Generic Text.LLVM.Triple.AST.ObjectFormat
+ Text.LLVM.Triple.AST: instance GHC.Generics.Generic Text.LLVM.Triple.AST.SubArch
+ Text.LLVM.Triple.AST: instance GHC.Generics.Generic Text.LLVM.Triple.AST.TargetTriple
+ Text.LLVM.Triple.AST: instance GHC.Generics.Generic Text.LLVM.Triple.AST.Vendor
+ Text.LLVM.Triple.AST: instance GHC.Read.Read Text.LLVM.Triple.AST.Arch
+ Text.LLVM.Triple.AST: instance GHC.Read.Read Text.LLVM.Triple.AST.Environment
+ Text.LLVM.Triple.AST: instance GHC.Read.Read Text.LLVM.Triple.AST.OS
+ Text.LLVM.Triple.AST: instance GHC.Read.Read Text.LLVM.Triple.AST.ObjectFormat
+ Text.LLVM.Triple.AST: instance GHC.Read.Read Text.LLVM.Triple.AST.SubArch
+ Text.LLVM.Triple.AST: instance GHC.Read.Read Text.LLVM.Triple.AST.TargetTriple
+ Text.LLVM.Triple.AST: instance GHC.Read.Read Text.LLVM.Triple.AST.Vendor
+ Text.LLVM.Triple.AST: instance GHC.Show.Show Text.LLVM.Triple.AST.Arch
+ Text.LLVM.Triple.AST: instance GHC.Show.Show Text.LLVM.Triple.AST.Environment
+ Text.LLVM.Triple.AST: instance GHC.Show.Show Text.LLVM.Triple.AST.OS
+ Text.LLVM.Triple.AST: instance GHC.Show.Show Text.LLVM.Triple.AST.ObjectFormat
+ Text.LLVM.Triple.AST: instance GHC.Show.Show Text.LLVM.Triple.AST.SubArch
+ Text.LLVM.Triple.AST: instance GHC.Show.Show Text.LLVM.Triple.AST.TargetTriple
+ Text.LLVM.Triple.AST: instance GHC.Show.Show Text.LLVM.Triple.AST.Vendor
+ Text.LLVM.Triple.Parse: parseArch :: String -> Arch
+ Text.LLVM.Triple.Parse: parseEnv :: String -> Environment
+ Text.LLVM.Triple.Parse: parseOS :: String -> OS
+ Text.LLVM.Triple.Parse: parseObjFmt :: String -> ObjectFormat
+ Text.LLVM.Triple.Parse: parseSubArch :: String -> SubArch
+ Text.LLVM.Triple.Parse: parseTriple :: String -> TargetTriple
+ Text.LLVM.Triple.Parse: parseVendor :: String -> Vendor
+ Text.LLVM.Triple.Print: archName :: Arch -> String
+ Text.LLVM.Triple.Print: envName :: Environment -> String
+ Text.LLVM.Triple.Print: objFmtName :: ObjectFormat -> String
+ Text.LLVM.Triple.Print: osName :: OS -> String
+ Text.LLVM.Triple.Print: printTriple :: TargetTriple -> String
+ Text.LLVM.Triple.Print: vendorName :: Vendor -> String
- Text.LLVM: FunAttrs :: Maybe Linkage -> Maybe GC -> FunAttrs
+ Text.LLVM: FunAttrs :: Maybe Linkage -> Maybe Visibility -> Maybe GC -> FunAttrs
- Text.LLVM: load :: IsValue a => Typed a -> Maybe Align -> BB (Typed Value)
+ Text.LLVM: load :: IsValue a => Type -> Typed a -> Maybe Align -> BB (Typed Value)
- Text.LLVM.AST: ConstBlockAddr :: Symbol -> lab -> ConstExpr' lab
+ Text.LLVM.AST: ConstBlockAddr :: Typed (Value' lab) -> lab -> ConstExpr' lab
- Text.LLVM.AST: ConstGEP :: Bool -> Maybe Word64 -> Maybe Type -> [Typed (Value' lab)] -> ConstExpr' lab
+ Text.LLVM.AST: ConstGEP :: Bool -> Maybe Word64 -> Type -> Typed (Value' lab) -> [Typed (Value' lab)] -> ConstExpr' lab
- Text.LLVM.AST: DICompileUnit :: DwarfLang -> Maybe (ValMd' lab) -> Maybe String -> Bool -> Maybe String -> Word16 -> Maybe FilePath -> DIEmissionKind -> Maybe (ValMd' lab) -> Maybe (ValMd' lab) -> Maybe (ValMd' lab) -> Maybe (ValMd' lab) -> Maybe (ValMd' lab) -> Maybe (ValMd' lab) -> Word64 -> Bool -> DICompileUnit' lab
+ Text.LLVM.AST: DICompileUnit :: DwarfLang -> Maybe (ValMd' lab) -> Maybe String -> Bool -> Maybe String -> Word16 -> Maybe FilePath -> DIEmissionKind -> Maybe (ValMd' lab) -> Maybe (ValMd' lab) -> Maybe (ValMd' lab) -> Maybe (ValMd' lab) -> Maybe (ValMd' lab) -> Maybe (ValMd' lab) -> Word64 -> Bool -> Bool -> Word64 -> Bool -> Maybe String -> Maybe String -> DICompileUnit' lab
- Text.LLVM.AST: DICompositeType :: DwarfTag -> Maybe String -> Maybe (ValMd' lab) -> Word32 -> Maybe (ValMd' lab) -> Maybe (ValMd' lab) -> Word64 -> Word64 -> Word64 -> DIFlags -> Maybe (ValMd' lab) -> DwarfLang -> Maybe (ValMd' lab) -> Maybe (ValMd' lab) -> Maybe String -> Maybe (ValMd' lab) -> DICompositeType' lab
+ Text.LLVM.AST: DICompositeType :: DwarfTag -> Maybe String -> Maybe (ValMd' lab) -> Word32 -> Maybe (ValMd' lab) -> Maybe (ValMd' lab) -> Word64 -> Word64 -> Word64 -> DIFlags -> Maybe (ValMd' lab) -> DwarfLang -> Maybe (ValMd' lab) -> Maybe (ValMd' lab) -> Maybe String -> Maybe (ValMd' lab) -> Maybe (ValMd' lab) -> Maybe (ValMd' lab) -> Maybe (ValMd' lab) -> Maybe (ValMd' lab) -> Maybe (ValMd' lab) -> DICompositeType' lab
- Text.LLVM.AST: DIDerivedType :: DwarfTag -> Maybe String -> Maybe (ValMd' lab) -> Word32 -> Maybe (ValMd' lab) -> Maybe (ValMd' lab) -> Word64 -> Word64 -> Word64 -> DIFlags -> Maybe (ValMd' lab) -> DIDerivedType' lab
+ Text.LLVM.AST: DIDerivedType :: DwarfTag -> Maybe String -> Maybe (ValMd' lab) -> Word32 -> Maybe (ValMd' lab) -> Maybe (ValMd' lab) -> Word64 -> Word64 -> Word64 -> DIFlags -> Maybe (ValMd' lab) -> Maybe Word32 -> Maybe (ValMd' lab) -> DIDerivedType' lab
- Text.LLVM.AST: DIGlobalVariable :: Maybe (ValMd' lab) -> Maybe String -> Maybe String -> Maybe (ValMd' lab) -> Word32 -> Maybe (ValMd' lab) -> Bool -> Bool -> Maybe (ValMd' lab) -> Maybe (ValMd' lab) -> Maybe Word32 -> DIGlobalVariable' lab
+ Text.LLVM.AST: DIGlobalVariable :: Maybe (ValMd' lab) -> Maybe String -> Maybe String -> Maybe (ValMd' lab) -> Word32 -> Maybe (ValMd' lab) -> Bool -> Bool -> Maybe (ValMd' lab) -> Maybe (ValMd' lab) -> Maybe Word32 -> Maybe (ValMd' lab) -> DIGlobalVariable' lab
- Text.LLVM.AST: DILocalVariable :: Maybe (ValMd' lab) -> Maybe String -> Maybe (ValMd' lab) -> Word32 -> Maybe (ValMd' lab) -> Word16 -> DIFlags -> DILocalVariable' lab
+ Text.LLVM.AST: DILocalVariable :: Maybe (ValMd' lab) -> Maybe String -> Maybe (ValMd' lab) -> Word32 -> Maybe (ValMd' lab) -> Word16 -> DIFlags -> Maybe Word32 -> Maybe (ValMd' lab) -> DILocalVariable' lab
- Text.LLVM.AST: DISubprogram :: Maybe (ValMd' lab) -> Maybe String -> Maybe String -> Maybe (ValMd' lab) -> Word32 -> Maybe (ValMd' lab) -> Bool -> Bool -> Word32 -> Maybe (ValMd' lab) -> DwarfVirtuality -> Word32 -> Int64 -> DIFlags -> Bool -> Maybe (ValMd' lab) -> Maybe (ValMd' lab) -> Maybe (ValMd' lab) -> Maybe (ValMd' lab) -> Maybe (ValMd' lab) -> DISubprogram' lab
+ Text.LLVM.AST: DISubprogram :: Maybe (ValMd' lab) -> Maybe String -> Maybe String -> Maybe (ValMd' lab) -> Word32 -> Maybe (ValMd' lab) -> Bool -> Bool -> Word32 -> Maybe (ValMd' lab) -> DwarfVirtuality -> Word32 -> Int64 -> DIFlags -> Bool -> Maybe (ValMd' lab) -> Maybe (ValMd' lab) -> Maybe (ValMd' lab) -> Maybe (ValMd' lab) -> Maybe (ValMd' lab) -> Maybe (ValMd' lab) -> DISubprogram' lab
- Text.LLVM.AST: DISubrange :: Int64 -> Int64 -> DISubrange
+ Text.LLVM.AST: DISubrange :: Maybe (ValMd' lab) -> Maybe (ValMd' lab) -> Maybe (ValMd' lab) -> Maybe (ValMd' lab) -> DISubrange' lab
- Text.LLVM.AST: DITemplateTypeParameter :: Maybe String -> Maybe (ValMd' lab) -> DITemplateTypeParameter' lab
+ Text.LLVM.AST: DITemplateTypeParameter :: Maybe String -> Maybe (ValMd' lab) -> Maybe Bool -> DITemplateTypeParameter' lab
- Text.LLVM.AST: DITemplateValueParameter :: DwarfTag -> Maybe String -> Maybe (ValMd' lab) -> ValMd' lab -> DITemplateValueParameter' lab
+ Text.LLVM.AST: DITemplateValueParameter :: DwarfTag -> Maybe String -> Maybe (ValMd' lab) -> Maybe Bool -> ValMd' lab -> DITemplateValueParameter' lab
- Text.LLVM.AST: DebugInfoEnumerator :: String -> !Int64 -> DebugInfo' lab
+ Text.LLVM.AST: DebugInfoEnumerator :: String -> !Integer -> Bool -> DebugInfo' lab
- Text.LLVM.AST: DebugInfoSubrange :: DISubrange -> DebugInfo' lab
+ Text.LLVM.AST: DebugInfoSubrange :: DISubrange' lab -> DebugInfo' lab
- Text.LLVM.AST: Declare :: Type -> Symbol -> [Type] -> Bool -> [FunAttr] -> Maybe String -> Declare
+ Text.LLVM.AST: Declare :: Maybe Linkage -> Maybe Visibility -> Type -> Symbol -> [Type] -> Bool -> [FunAttr] -> Maybe String -> Declare
- Text.LLVM.AST: Define :: Maybe Linkage -> Type -> Symbol -> [Typed Ident] -> Bool -> [FunAttr] -> Maybe String -> Maybe GC -> [BasicBlock] -> FnMdAttachments -> Maybe String -> Define
+ Text.LLVM.AST: Define :: Maybe Linkage -> Maybe Visibility -> Type -> Symbol -> [Typed Ident] -> Bool -> [FunAttr] -> Maybe String -> Maybe GC -> [BasicBlock] -> FnMdAttachments -> Maybe String -> Define
- Text.LLVM.AST: GEP :: Bool -> Typed (Value' lab) -> [Typed (Value' lab)] -> Instr' lab
+ Text.LLVM.AST: GEP :: Bool -> Type -> Typed (Value' lab) -> [Typed (Value' lab)] -> Instr' lab
- Text.LLVM.AST: GlobalAlias :: Symbol -> Type -> Value -> GlobalAlias
+ Text.LLVM.AST: GlobalAlias :: Maybe Linkage -> Maybe Visibility -> Symbol -> Type -> Value -> GlobalAlias
- Text.LLVM.AST: Load :: Typed (Value' lab) -> Maybe AtomicOrdering -> Maybe Align -> Instr' lab
+ Text.LLVM.AST: Load :: Type -> Typed (Value' lab) -> Maybe AtomicOrdering -> Maybe Align -> Instr' lab
- Text.LLVM.AST: Module :: Maybe String -> DataLayout -> [TypeDecl] -> [NamedMd] -> [UnnamedMd] -> Map String SelectionKind -> [Global] -> [Declare] -> [Define] -> InlineAsm -> [GlobalAlias] -> Module
+ Text.LLVM.AST: Module :: Maybe String -> TargetTriple -> DataLayout -> [TypeDecl] -> [NamedMd] -> [UnnamedMd] -> Map String SelectionKind -> [Global] -> [Declare] -> [Define] -> InlineAsm -> [GlobalAlias] -> Module
- Text.LLVM.AST: [disrCount] :: DISubrange -> Int64
+ Text.LLVM.AST: [disrCount] :: DISubrange' lab -> Maybe (ValMd' lab)
- Text.LLVM.AST: [disrLowerBound] :: DISubrange -> Int64
+ Text.LLVM.AST: [disrLowerBound] :: DISubrange' lab -> Maybe (ValMd' lab)
- Text.LLVM.AST: resolveGep :: Type -> [Typed (Value' lab)] -> IndexResult
+ Text.LLVM.AST: resolveGep :: Type -> Typed (Value' lab) -> [Typed (Value' lab)] -> IndexResult
- Text.LLVM.AST: resolveGepFull :: (Ident -> Maybe Type) -> Type -> [Typed (Value' lab)] -> Maybe Type
+ Text.LLVM.AST: resolveGepFull :: (Ident -> Maybe Type) -> Type -> Typed (Value' lab) -> [Typed (Value' lab)] -> Maybe Type
- Text.LLVM.DebugUtils: BaseType :: String -> Info
+ Text.LLVM.DebugUtils: BaseType :: String -> DIBasicType -> Info
- Text.LLVM.DebugUtils: Structure :: [(String, Word64, Info)] -> Info
+ Text.LLVM.DebugUtils: Structure :: Maybe String -> [StructFieldInfo] -> Info
- Text.LLVM.DebugUtils: Union :: [(String, Info)] -> Info
+ Text.LLVM.DebugUtils: Union :: Maybe String -> [UnionFieldInfo] -> Info
- Text.LLVM.DebugUtils: computeFunctionTypes :: Module -> Symbol -> Maybe [Info]
+ Text.LLVM.DebugUtils: computeFunctionTypes :: Module -> Symbol -> Maybe [Maybe Info]
- Text.LLVM.Lens: bbLabelLens :: forall lab_a9ig. Lens' (BasicBlock' lab_a9ig) (Maybe lab_a9ig)
+ Text.LLVM.Lens: bbLabelLens :: forall lab_i4aJq. Lens' (BasicBlock' lab_i4aJq) (Maybe lab_i4aJq)
- Text.LLVM.Lens: bbStmtsLens :: forall lab_a9ig. Lens' (BasicBlock' lab_a9ig) [Stmt' lab_a9ig]
+ Text.LLVM.Lens: bbStmtsLens :: forall lab_i4aJq. Lens' (BasicBlock' lab_i4aJq) [Stmt' lab_i4aJq]
- Text.LLVM.Lens: dictAlignLens :: forall lab_a8Ob. Lens' (DICompositeType' lab_a8Ob) Word64
+ Text.LLVM.Lens: dictAlignLens :: forall lab_i4ayD. Lens' (DICompositeType' lab_i4ayD) Word64
- Text.LLVM.Lens: dictBaseTypeLens :: forall lab_a8Ob. Lens' (DICompositeType' lab_a8Ob) (Maybe (ValMd' lab_a8Ob))
+ Text.LLVM.Lens: dictBaseTypeLens :: forall lab_i4ayD. Lens' (DICompositeType' lab_i4ayD) (Maybe (ValMd' lab_i4ayD))
- Text.LLVM.Lens: dictDiscriminatorLens :: forall lab_a8Ob. Lens' (DICompositeType' lab_a8Ob) (Maybe (ValMd' lab_a8Ob))
+ Text.LLVM.Lens: dictDiscriminatorLens :: forall lab_i4ayD. Lens' (DICompositeType' lab_i4ayD) (Maybe (ValMd' lab_i4ayD))
- Text.LLVM.Lens: dictElementsLens :: forall lab_a8Ob. Lens' (DICompositeType' lab_a8Ob) (Maybe (ValMd' lab_a8Ob))
+ Text.LLVM.Lens: dictElementsLens :: forall lab_i4ayD. Lens' (DICompositeType' lab_i4ayD) (Maybe (ValMd' lab_i4ayD))
- Text.LLVM.Lens: dictFileLens :: forall lab_a8Ob. Lens' (DICompositeType' lab_a8Ob) (Maybe (ValMd' lab_a8Ob))
+ Text.LLVM.Lens: dictFileLens :: forall lab_i4ayD. Lens' (DICompositeType' lab_i4ayD) (Maybe (ValMd' lab_i4ayD))
- Text.LLVM.Lens: dictFlagsLens :: forall lab_a8Ob. Lens' (DICompositeType' lab_a8Ob) DIFlags
+ Text.LLVM.Lens: dictFlagsLens :: forall lab_i4ayD. Lens' (DICompositeType' lab_i4ayD) DIFlags
- Text.LLVM.Lens: dictIdentifierLens :: forall lab_a8Ob. Lens' (DICompositeType' lab_a8Ob) (Maybe String)
+ Text.LLVM.Lens: dictIdentifierLens :: forall lab_i4ayD. Lens' (DICompositeType' lab_i4ayD) (Maybe String)
- Text.LLVM.Lens: dictLineLens :: forall lab_a8Ob. Lens' (DICompositeType' lab_a8Ob) Word32
+ Text.LLVM.Lens: dictLineLens :: forall lab_i4ayD. Lens' (DICompositeType' lab_i4ayD) Word32
- Text.LLVM.Lens: dictNameLens :: forall lab_a8Ob. Lens' (DICompositeType' lab_a8Ob) (Maybe String)
+ Text.LLVM.Lens: dictNameLens :: forall lab_i4ayD. Lens' (DICompositeType' lab_i4ayD) (Maybe String)
- Text.LLVM.Lens: dictOffsetLens :: forall lab_a8Ob. Lens' (DICompositeType' lab_a8Ob) Word64
+ Text.LLVM.Lens: dictOffsetLens :: forall lab_i4ayD. Lens' (DICompositeType' lab_i4ayD) Word64
- Text.LLVM.Lens: dictRuntimeLangLens :: forall lab_a8Ob. Lens' (DICompositeType' lab_a8Ob) DwarfLang
+ Text.LLVM.Lens: dictRuntimeLangLens :: forall lab_i4ayD. Lens' (DICompositeType' lab_i4ayD) DwarfLang
- Text.LLVM.Lens: dictScopeLens :: forall lab_a8Ob. Lens' (DICompositeType' lab_a8Ob) (Maybe (ValMd' lab_a8Ob))
+ Text.LLVM.Lens: dictScopeLens :: forall lab_i4ayD. Lens' (DICompositeType' lab_i4ayD) (Maybe (ValMd' lab_i4ayD))
- Text.LLVM.Lens: dictSizeLens :: forall lab_a8Ob. Lens' (DICompositeType' lab_a8Ob) Word64
+ Text.LLVM.Lens: dictSizeLens :: forall lab_i4ayD. Lens' (DICompositeType' lab_i4ayD) Word64
- Text.LLVM.Lens: dictTagLens :: forall lab_a8Ob. Lens' (DICompositeType' lab_a8Ob) DwarfTag
+ Text.LLVM.Lens: dictTagLens :: forall lab_i4ayD. Lens' (DICompositeType' lab_i4ayD) DwarfTag
- Text.LLVM.Lens: dictTemplateParamsLens :: forall lab_a8Ob. Lens' (DICompositeType' lab_a8Ob) (Maybe (ValMd' lab_a8Ob))
+ Text.LLVM.Lens: dictTemplateParamsLens :: forall lab_i4ayD. Lens' (DICompositeType' lab_i4ayD) (Maybe (ValMd' lab_i4ayD))
- Text.LLVM.Lens: dictVTableHolderLens :: forall lab_a8Ob. Lens' (DICompositeType' lab_a8Ob) (Maybe (ValMd' lab_a8Ob))
+ Text.LLVM.Lens: dictVTableHolderLens :: forall lab_i4ayD. Lens' (DICompositeType' lab_i4ayD) (Maybe (ValMd' lab_i4ayD))
- Text.LLVM.Lens: dicuDWOIdLens :: forall lab_a8Oc. Lens' (DICompileUnit' lab_a8Oc) Word64
+ Text.LLVM.Lens: dicuDWOIdLens :: forall lab_i4axB. Lens' (DICompileUnit' lab_i4axB) Word64
- Text.LLVM.Lens: dicuEmissionKindLens :: forall lab_a8Oc. Lens' (DICompileUnit' lab_a8Oc) DIEmissionKind
+ Text.LLVM.Lens: dicuEmissionKindLens :: forall lab_i4axB. Lens' (DICompileUnit' lab_i4axB) DIEmissionKind
- Text.LLVM.Lens: dicuEnumsLens :: forall lab_a8Oc. Lens' (DICompileUnit' lab_a8Oc) (Maybe (ValMd' lab_a8Oc))
+ Text.LLVM.Lens: dicuEnumsLens :: forall lab_i4axB. Lens' (DICompileUnit' lab_i4axB) (Maybe (ValMd' lab_i4axB))
- Text.LLVM.Lens: dicuFileLens :: forall lab_a8Oc. Lens' (DICompileUnit' lab_a8Oc) (Maybe (ValMd' lab_a8Oc))
+ Text.LLVM.Lens: dicuFileLens :: forall lab_i4axB. Lens' (DICompileUnit' lab_i4axB) (Maybe (ValMd' lab_i4axB))
- Text.LLVM.Lens: dicuFlagsLens :: forall lab_a8Oc. Lens' (DICompileUnit' lab_a8Oc) (Maybe String)
+ Text.LLVM.Lens: dicuFlagsLens :: forall lab_i4axB. Lens' (DICompileUnit' lab_i4axB) (Maybe String)
- Text.LLVM.Lens: dicuGlobalsLens :: forall lab_a8Oc. Lens' (DICompileUnit' lab_a8Oc) (Maybe (ValMd' lab_a8Oc))
+ Text.LLVM.Lens: dicuGlobalsLens :: forall lab_i4axB. Lens' (DICompileUnit' lab_i4axB) (Maybe (ValMd' lab_i4axB))
- Text.LLVM.Lens: dicuImportsLens :: forall lab_a8Oc. Lens' (DICompileUnit' lab_a8Oc) (Maybe (ValMd' lab_a8Oc))
+ Text.LLVM.Lens: dicuImportsLens :: forall lab_i4axB. Lens' (DICompileUnit' lab_i4axB) (Maybe (ValMd' lab_i4axB))
- Text.LLVM.Lens: dicuIsOptimizedLens :: forall lab_a8Oc. Lens' (DICompileUnit' lab_a8Oc) Bool
+ Text.LLVM.Lens: dicuIsOptimizedLens :: forall lab_i4axB. Lens' (DICompileUnit' lab_i4axB) Bool
- Text.LLVM.Lens: dicuLanguageLens :: forall lab_a8Oc. Lens' (DICompileUnit' lab_a8Oc) DwarfLang
+ Text.LLVM.Lens: dicuLanguageLens :: forall lab_i4axB. Lens' (DICompileUnit' lab_i4axB) DwarfLang
- Text.LLVM.Lens: dicuMacrosLens :: forall lab_a8Oc. Lens' (DICompileUnit' lab_a8Oc) (Maybe (ValMd' lab_a8Oc))
+ Text.LLVM.Lens: dicuMacrosLens :: forall lab_i4axB. Lens' (DICompileUnit' lab_i4axB) (Maybe (ValMd' lab_i4axB))
- Text.LLVM.Lens: dicuProducerLens :: forall lab_a8Oc. Lens' (DICompileUnit' lab_a8Oc) (Maybe String)
+ Text.LLVM.Lens: dicuProducerLens :: forall lab_i4axB. Lens' (DICompileUnit' lab_i4axB) (Maybe String)
- Text.LLVM.Lens: dicuRetainedTypesLens :: forall lab_a8Oc. Lens' (DICompileUnit' lab_a8Oc) (Maybe (ValMd' lab_a8Oc))
+ Text.LLVM.Lens: dicuRetainedTypesLens :: forall lab_i4axB. Lens' (DICompileUnit' lab_i4axB) (Maybe (ValMd' lab_i4axB))
- Text.LLVM.Lens: dicuRuntimeVersionLens :: forall lab_a8Oc. Lens' (DICompileUnit' lab_a8Oc) Word16
+ Text.LLVM.Lens: dicuRuntimeVersionLens :: forall lab_i4axB. Lens' (DICompileUnit' lab_i4axB) Word16
- Text.LLVM.Lens: dicuSplitDebugFilenameLens :: forall lab_a8Oc. Lens' (DICompileUnit' lab_a8Oc) (Maybe FilePath)
+ Text.LLVM.Lens: dicuSplitDebugFilenameLens :: forall lab_i4axB. Lens' (DICompileUnit' lab_i4axB) (Maybe FilePath)
- Text.LLVM.Lens: dicuSplitDebugInliningLens :: forall lab_a8Oc. Lens' (DICompileUnit' lab_a8Oc) Bool
+ Text.LLVM.Lens: dicuSplitDebugInliningLens :: forall lab_i4axB. Lens' (DICompileUnit' lab_i4axB) Bool
- Text.LLVM.Lens: dicuSubprogramsLens :: forall lab_a8Oc. Lens' (DICompileUnit' lab_a8Oc) (Maybe (ValMd' lab_a8Oc))
+ Text.LLVM.Lens: dicuSubprogramsLens :: forall lab_i4axB. Lens' (DICompileUnit' lab_i4axB) (Maybe (ValMd' lab_i4axB))
- Text.LLVM.Lens: didtAlignLens :: forall lab_a8Oa. Lens' (DIDerivedType' lab_a8Oa) Word64
+ Text.LLVM.Lens: didtAlignLens :: forall lab_i4aC6. Lens' (DIDerivedType' lab_i4aC6) Word64
- Text.LLVM.Lens: didtBaseTypeLens :: forall lab_a8Oa. Lens' (DIDerivedType' lab_a8Oa) (Maybe (ValMd' lab_a8Oa))
+ Text.LLVM.Lens: didtBaseTypeLens :: forall lab_i4aC6. Lens' (DIDerivedType' lab_i4aC6) (Maybe (ValMd' lab_i4aC6))
- Text.LLVM.Lens: didtExtraDataLens :: forall lab_a8Oa. Lens' (DIDerivedType' lab_a8Oa) (Maybe (ValMd' lab_a8Oa))
+ Text.LLVM.Lens: didtExtraDataLens :: forall lab_i4aC6. Lens' (DIDerivedType' lab_i4aC6) (Maybe (ValMd' lab_i4aC6))
- Text.LLVM.Lens: didtFileLens :: forall lab_a8Oa. Lens' (DIDerivedType' lab_a8Oa) (Maybe (ValMd' lab_a8Oa))
+ Text.LLVM.Lens: didtFileLens :: forall lab_i4aC6. Lens' (DIDerivedType' lab_i4aC6) (Maybe (ValMd' lab_i4aC6))
- Text.LLVM.Lens: didtFlagsLens :: forall lab_a8Oa. Lens' (DIDerivedType' lab_a8Oa) DIFlags
+ Text.LLVM.Lens: didtFlagsLens :: forall lab_i4aC6. Lens' (DIDerivedType' lab_i4aC6) DIFlags
- Text.LLVM.Lens: didtLineLens :: forall lab_a8Oa. Lens' (DIDerivedType' lab_a8Oa) Word32
+ Text.LLVM.Lens: didtLineLens :: forall lab_i4aC6. Lens' (DIDerivedType' lab_i4aC6) Word32
- Text.LLVM.Lens: didtNameLens :: forall lab_a8Oa. Lens' (DIDerivedType' lab_a8Oa) (Maybe String)
+ Text.LLVM.Lens: didtNameLens :: forall lab_i4aC6. Lens' (DIDerivedType' lab_i4aC6) (Maybe String)
- Text.LLVM.Lens: didtOffsetLens :: forall lab_a8Oa. Lens' (DIDerivedType' lab_a8Oa) Word64
+ Text.LLVM.Lens: didtOffsetLens :: forall lab_i4aC6. Lens' (DIDerivedType' lab_i4aC6) Word64
- Text.LLVM.Lens: didtScopeLens :: forall lab_a8Oa. Lens' (DIDerivedType' lab_a8Oa) (Maybe (ValMd' lab_a8Oa))
+ Text.LLVM.Lens: didtScopeLens :: forall lab_i4aC6. Lens' (DIDerivedType' lab_i4aC6) (Maybe (ValMd' lab_i4aC6))
- Text.LLVM.Lens: didtSizeLens :: forall lab_a8Oa. Lens' (DIDerivedType' lab_a8Oa) Word64
+ Text.LLVM.Lens: didtSizeLens :: forall lab_i4aC6. Lens' (DIDerivedType' lab_i4aC6) Word64
- Text.LLVM.Lens: didtTagLens :: forall lab_a8Oa. Lens' (DIDerivedType' lab_a8Oa) DwarfTag
+ Text.LLVM.Lens: didtTagLens :: forall lab_i4aC6. Lens' (DIDerivedType' lab_i4aC6) DwarfTag
- Text.LLVM.Lens: digvAlignmentLens :: forall lab_a8M0. Lens' (DIGlobalVariable' lab_a8M0) (Maybe Word32)
+ Text.LLVM.Lens: digvAlignmentLens :: forall lab_i4aAU. Lens' (DIGlobalVariable' lab_i4aAU) (Maybe Word32)
- Text.LLVM.Lens: digvDeclarationLens :: forall lab_a8M0. Lens' (DIGlobalVariable' lab_a8M0) (Maybe (ValMd' lab_a8M0))
+ Text.LLVM.Lens: digvDeclarationLens :: forall lab_i4aAU. Lens' (DIGlobalVariable' lab_i4aAU) (Maybe (ValMd' lab_i4aAU))
- Text.LLVM.Lens: digvFileLens :: forall lab_a8M0. Lens' (DIGlobalVariable' lab_a8M0) (Maybe (ValMd' lab_a8M0))
+ Text.LLVM.Lens: digvFileLens :: forall lab_i4aAU. Lens' (DIGlobalVariable' lab_i4aAU) (Maybe (ValMd' lab_i4aAU))
- Text.LLVM.Lens: digvIsDefinitionLens :: forall lab_a8M0. Lens' (DIGlobalVariable' lab_a8M0) Bool
+ Text.LLVM.Lens: digvIsDefinitionLens :: forall lab_i4aAU. Lens' (DIGlobalVariable' lab_i4aAU) Bool
- Text.LLVM.Lens: digvIsLocalLens :: forall lab_a8M0. Lens' (DIGlobalVariable' lab_a8M0) Bool
+ Text.LLVM.Lens: digvIsLocalLens :: forall lab_i4aAU. Lens' (DIGlobalVariable' lab_i4aAU) Bool
- Text.LLVM.Lens: digvLineLens :: forall lab_a8M0. Lens' (DIGlobalVariable' lab_a8M0) Word32
+ Text.LLVM.Lens: digvLineLens :: forall lab_i4aAU. Lens' (DIGlobalVariable' lab_i4aAU) Word32
- Text.LLVM.Lens: digvLinkageNameLens :: forall lab_a8M0. Lens' (DIGlobalVariable' lab_a8M0) (Maybe String)
+ Text.LLVM.Lens: digvLinkageNameLens :: forall lab_i4aAU. Lens' (DIGlobalVariable' lab_i4aAU) (Maybe String)
- Text.LLVM.Lens: digvNameLens :: forall lab_a8M0. Lens' (DIGlobalVariable' lab_a8M0) (Maybe String)
+ Text.LLVM.Lens: digvNameLens :: forall lab_i4aAU. Lens' (DIGlobalVariable' lab_i4aAU) (Maybe String)
- Text.LLVM.Lens: digvScopeLens :: forall lab_a8M0. Lens' (DIGlobalVariable' lab_a8M0) (Maybe (ValMd' lab_a8M0))
+ Text.LLVM.Lens: digvScopeLens :: forall lab_i4aAU. Lens' (DIGlobalVariable' lab_i4aAU) (Maybe (ValMd' lab_i4aAU))
- Text.LLVM.Lens: digvTypeLens :: forall lab_a8M0. Lens' (DIGlobalVariable' lab_a8M0) (Maybe (ValMd' lab_a8M0))
+ Text.LLVM.Lens: digvTypeLens :: forall lab_i4aAU. Lens' (DIGlobalVariable' lab_i4aAU) (Maybe (ValMd' lab_i4aAU))
- Text.LLVM.Lens: digvVariableLens :: forall lab_a8M0. Lens' (DIGlobalVariable' lab_a8M0) (Maybe (ValMd' lab_a8M0))
+ Text.LLVM.Lens: digvVariableLens :: forall lab_i4aAU. Lens' (DIGlobalVariable' lab_i4aAU) (Maybe (ValMd' lab_i4aAU))
- Text.LLVM.Lens: digveExpressionLens :: forall lab_a8LZ. Lens' (DIGlobalVariableExpression' lab_a8LZ) (Maybe (ValMd' lab_a8LZ))
+ Text.LLVM.Lens: digveExpressionLens :: forall lab_i4aAB. Lens' (DIGlobalVariableExpression' lab_i4aAB) (Maybe (ValMd' lab_i4aAB))
- Text.LLVM.Lens: digveVariableLens :: forall lab_a8LZ. Lens' (DIGlobalVariableExpression' lab_a8LZ) (Maybe (ValMd' lab_a8LZ))
+ Text.LLVM.Lens: digveVariableLens :: forall lab_i4aAB. Lens' (DIGlobalVariableExpression' lab_i4aAB) (Maybe (ValMd' lab_i4aAB))
- Text.LLVM.Lens: dilbColumnLens :: forall lab_a8LY. Lens' (DILexicalBlock' lab_a8LY) Word16
+ Text.LLVM.Lens: dilbColumnLens :: forall lab_i4ayi. Lens' (DILexicalBlock' lab_i4ayi) Word16
- Text.LLVM.Lens: dilbFileLens :: forall lab_a8LY. Lens' (DILexicalBlock' lab_a8LY) (Maybe (ValMd' lab_a8LY))
+ Text.LLVM.Lens: dilbFileLens :: forall lab_i4ayi. Lens' (DILexicalBlock' lab_i4ayi) (Maybe (ValMd' lab_i4ayi))
- Text.LLVM.Lens: dilbLineLens :: forall lab_a8LY. Lens' (DILexicalBlock' lab_a8LY) Word32
+ Text.LLVM.Lens: dilbLineLens :: forall lab_i4ayi. Lens' (DILexicalBlock' lab_i4ayi) Word32
- Text.LLVM.Lens: dilbScopeLens :: forall lab_a8LY. Lens' (DILexicalBlock' lab_a8LY) (Maybe (ValMd' lab_a8LY))
+ Text.LLVM.Lens: dilbScopeLens :: forall lab_i4ayi. Lens' (DILexicalBlock' lab_i4ayi) (Maybe (ValMd' lab_i4ayi))
- Text.LLVM.Lens: dilbfDiscriminatorLens :: forall lab_a8LX. Lens' (DILexicalBlockFile' lab_a8LX) Word32
+ Text.LLVM.Lens: dilbfDiscriminatorLens :: forall lab_i4axh. Lens' (DILexicalBlockFile' lab_i4axh) Word32
- Text.LLVM.Lens: dilbfFileLens :: forall lab_a8LX. Lens' (DILexicalBlockFile' lab_a8LX) (Maybe (ValMd' lab_a8LX))
+ Text.LLVM.Lens: dilbfFileLens :: forall lab_i4axh. Lens' (DILexicalBlockFile' lab_i4axh) (Maybe (ValMd' lab_i4axh))
- Text.LLVM.Lens: dilbfScopeLens :: forall lab_a8LX. Lens' (DILexicalBlockFile' lab_a8LX) (ValMd' lab_a8LX)
+ Text.LLVM.Lens: dilbfScopeLens :: forall lab_i4axh. Lens' (DILexicalBlockFile' lab_i4axh) (ValMd' lab_i4axh)
- Text.LLVM.Lens: dilvArgLens :: forall lab_a8LW. Lens' (DILocalVariable' lab_a8LW) Word16
+ Text.LLVM.Lens: dilvArgLens :: forall lab_i4aA9. Lens' (DILocalVariable' lab_i4aA9) Word16
- Text.LLVM.Lens: dilvFileLens :: forall lab_a8LW. Lens' (DILocalVariable' lab_a8LW) (Maybe (ValMd' lab_a8LW))
+ Text.LLVM.Lens: dilvFileLens :: forall lab_i4aA9. Lens' (DILocalVariable' lab_i4aA9) (Maybe (ValMd' lab_i4aA9))
- Text.LLVM.Lens: dilvFlagsLens :: forall lab_a8LW. Lens' (DILocalVariable' lab_a8LW) DIFlags
+ Text.LLVM.Lens: dilvFlagsLens :: forall lab_i4aA9. Lens' (DILocalVariable' lab_i4aA9) DIFlags
- Text.LLVM.Lens: dilvLineLens :: forall lab_a8LW. Lens' (DILocalVariable' lab_a8LW) Word32
+ Text.LLVM.Lens: dilvLineLens :: forall lab_i4aA9. Lens' (DILocalVariable' lab_i4aA9) Word32
- Text.LLVM.Lens: dilvNameLens :: forall lab_a8LW. Lens' (DILocalVariable' lab_a8LW) (Maybe String)
+ Text.LLVM.Lens: dilvNameLens :: forall lab_i4aA9. Lens' (DILocalVariable' lab_i4aA9) (Maybe String)
- Text.LLVM.Lens: dilvScopeLens :: forall lab_a8LW. Lens' (DILocalVariable' lab_a8LW) (Maybe (ValMd' lab_a8LW))
+ Text.LLVM.Lens: dilvScopeLens :: forall lab_i4aA9. Lens' (DILocalVariable' lab_i4aA9) (Maybe (ValMd' lab_i4aA9))
- Text.LLVM.Lens: dilvTypeLens :: forall lab_a8LW. Lens' (DILocalVariable' lab_a8LW) (Maybe (ValMd' lab_a8LW))
+ Text.LLVM.Lens: dilvTypeLens :: forall lab_i4aA9. Lens' (DILocalVariable' lab_i4aA9) (Maybe (ValMd' lab_i4aA9))
- Text.LLVM.Lens: dispContainingTypeLens :: forall lab_a86F. Lens' (DISubprogram' lab_a86F) (Maybe (ValMd' lab_a86F))
+ Text.LLVM.Lens: dispContainingTypeLens :: forall lab_i4azp. Lens' (DISubprogram' lab_i4azp) (Maybe (ValMd' lab_i4azp))
- Text.LLVM.Lens: dispDeclarationLens :: forall lab_a86F. Lens' (DISubprogram' lab_a86F) (Maybe (ValMd' lab_a86F))
+ Text.LLVM.Lens: dispDeclarationLens :: forall lab_i4azp. Lens' (DISubprogram' lab_i4azp) (Maybe (ValMd' lab_i4azp))
- Text.LLVM.Lens: dispFileLens :: forall lab_a86F. Lens' (DISubprogram' lab_a86F) (Maybe (ValMd' lab_a86F))
+ Text.LLVM.Lens: dispFileLens :: forall lab_i4azp. Lens' (DISubprogram' lab_i4azp) (Maybe (ValMd' lab_i4azp))
- Text.LLVM.Lens: dispFlagsLens :: forall lab_a86F. Lens' (DISubprogram' lab_a86F) DIFlags
+ Text.LLVM.Lens: dispFlagsLens :: forall lab_i4azp. Lens' (DISubprogram' lab_i4azp) DIFlags
- Text.LLVM.Lens: dispIsDefinitionLens :: forall lab_a86F. Lens' (DISubprogram' lab_a86F) Bool
+ Text.LLVM.Lens: dispIsDefinitionLens :: forall lab_i4azp. Lens' (DISubprogram' lab_i4azp) Bool
- Text.LLVM.Lens: dispIsLocalLens :: forall lab_a86F. Lens' (DISubprogram' lab_a86F) Bool
+ Text.LLVM.Lens: dispIsLocalLens :: forall lab_i4azp. Lens' (DISubprogram' lab_i4azp) Bool
- Text.LLVM.Lens: dispIsOptimizedLens :: forall lab_a86F. Lens' (DISubprogram' lab_a86F) Bool
+ Text.LLVM.Lens: dispIsOptimizedLens :: forall lab_i4azp. Lens' (DISubprogram' lab_i4azp) Bool
- Text.LLVM.Lens: dispLineLens :: forall lab_a86F. Lens' (DISubprogram' lab_a86F) Word32
+ Text.LLVM.Lens: dispLineLens :: forall lab_i4azp. Lens' (DISubprogram' lab_i4azp) Word32
- Text.LLVM.Lens: dispLinkageNameLens :: forall lab_a86F. Lens' (DISubprogram' lab_a86F) (Maybe String)
+ Text.LLVM.Lens: dispLinkageNameLens :: forall lab_i4azp. Lens' (DISubprogram' lab_i4azp) (Maybe String)
- Text.LLVM.Lens: dispNameLens :: forall lab_a86F. Lens' (DISubprogram' lab_a86F) (Maybe String)
+ Text.LLVM.Lens: dispNameLens :: forall lab_i4azp. Lens' (DISubprogram' lab_i4azp) (Maybe String)
- Text.LLVM.Lens: dispScopeLens :: forall lab_a86F. Lens' (DISubprogram' lab_a86F) (Maybe (ValMd' lab_a86F))
+ Text.LLVM.Lens: dispScopeLens :: forall lab_i4azp. Lens' (DISubprogram' lab_i4azp) (Maybe (ValMd' lab_i4azp))
- Text.LLVM.Lens: dispScopeLineLens :: forall lab_a86F. Lens' (DISubprogram' lab_a86F) Word32
+ Text.LLVM.Lens: dispScopeLineLens :: forall lab_i4azp. Lens' (DISubprogram' lab_i4azp) Word32
- Text.LLVM.Lens: dispTemplateParamsLens :: forall lab_a86F. Lens' (DISubprogram' lab_a86F) (Maybe (ValMd' lab_a86F))
+ Text.LLVM.Lens: dispTemplateParamsLens :: forall lab_i4azp. Lens' (DISubprogram' lab_i4azp) (Maybe (ValMd' lab_i4azp))
- Text.LLVM.Lens: dispThisAdjustmentLens :: forall lab_a86F. Lens' (DISubprogram' lab_a86F) Int64
+ Text.LLVM.Lens: dispThisAdjustmentLens :: forall lab_i4azp. Lens' (DISubprogram' lab_i4azp) Int64
- Text.LLVM.Lens: dispThrownTypesLens :: forall lab_a86F. Lens' (DISubprogram' lab_a86F) (Maybe (ValMd' lab_a86F))
+ Text.LLVM.Lens: dispThrownTypesLens :: forall lab_i4azp. Lens' (DISubprogram' lab_i4azp) (Maybe (ValMd' lab_i4azp))
- Text.LLVM.Lens: dispTypeLens :: forall lab_a86F. Lens' (DISubprogram' lab_a86F) (Maybe (ValMd' lab_a86F))
+ Text.LLVM.Lens: dispTypeLens :: forall lab_i4azp. Lens' (DISubprogram' lab_i4azp) (Maybe (ValMd' lab_i4azp))
- Text.LLVM.Lens: dispUnitLens :: forall lab_a86F. Lens' (DISubprogram' lab_a86F) (Maybe (ValMd' lab_a86F))
+ Text.LLVM.Lens: dispUnitLens :: forall lab_i4azp. Lens' (DISubprogram' lab_i4azp) (Maybe (ValMd' lab_i4azp))
- Text.LLVM.Lens: dispVirtualIndexLens :: forall lab_a86F. Lens' (DISubprogram' lab_a86F) Word32
+ Text.LLVM.Lens: dispVirtualIndexLens :: forall lab_i4azp. Lens' (DISubprogram' lab_i4azp) Word32
- Text.LLVM.Lens: dispVirtualityLens :: forall lab_a86F. Lens' (DISubprogram' lab_a86F) DwarfVirtuality
+ Text.LLVM.Lens: dispVirtualityLens :: forall lab_i4azp. Lens' (DISubprogram' lab_i4azp) DwarfVirtuality
- Text.LLVM.Lens: disrCountLens :: Lens' DISubrange Int64
+ Text.LLVM.Lens: disrCountLens :: forall lab_i4aBr. Lens' (DISubrange' lab_i4aBr) (Maybe (ValMd' lab_i4aBr))
- Text.LLVM.Lens: disrLowerBoundLens :: Lens' DISubrange Int64
+ Text.LLVM.Lens: disrLowerBoundLens :: forall lab_i4aBr. Lens' (DISubrange' lab_i4aBr) (Maybe (ValMd' lab_i4aBr))
- Text.LLVM.Lens: distFlagsLens :: forall lab_a6EY. Lens' (DISubroutineType' lab_a6EY) DIFlags
+ Text.LLVM.Lens: distFlagsLens :: forall lab_i4aBO. Lens' (DISubroutineType' lab_i4aBO) DIFlags
- Text.LLVM.Lens: distTypeArrayLens :: forall lab_a6EY lab_a2ZVX. Lens (DISubroutineType' lab_a6EY) (DISubroutineType' lab_a2ZVX) (Maybe (ValMd' lab_a6EY)) (Maybe (ValMd' lab_a2ZVX))
+ Text.LLVM.Lens: distTypeArrayLens :: forall lab_i4aBO lab_a4kKW. Lens (DISubroutineType' lab_i4aBO) (DISubroutineType' lab_a4kKW) (Maybe (ValMd' lab_i4aBO)) (Maybe (ValMd' lab_a4kKW))
- Text.LLVM.Lens: dlColLens :: forall lab_a8Ol. Lens' (DebugLoc' lab_a8Ol) Word32
+ Text.LLVM.Lens: dlColLens :: forall lab_i4aDS. Lens' (DebugLoc' lab_i4aDS) Word32
- Text.LLVM.Lens: dlIALens :: forall lab_a8Ol. Lens' (DebugLoc' lab_a8Ol) (Maybe (ValMd' lab_a8Ol))
+ Text.LLVM.Lens: dlIALens :: forall lab_i4aDS. Lens' (DebugLoc' lab_i4aDS) (Maybe (ValMd' lab_i4aDS))
- Text.LLVM.Lens: dlImplicitLens :: forall lab_a8Ol. Lens' (DebugLoc' lab_a8Ol) Bool
+ Text.LLVM.Lens: dlImplicitLens :: forall lab_i4aDS. Lens' (DebugLoc' lab_i4aDS) Bool
- Text.LLVM.Lens: dlLineLens :: forall lab_a8Ol. Lens' (DebugLoc' lab_a8Ol) Word32
+ Text.LLVM.Lens: dlLineLens :: forall lab_i4aDS. Lens' (DebugLoc' lab_i4aDS) Word32
- Text.LLVM.Lens: dlScopeLens :: forall lab_a8Ol. Lens' (DebugLoc' lab_a8Ol) (ValMd' lab_a8Ol)
+ Text.LLVM.Lens: dlScopeLens :: forall lab_i4aDS. Lens' (DebugLoc' lab_i4aDS) (ValMd' lab_i4aDS)
- Text.LLVM.Lens: typedTypeLens :: forall a_a9if. Lens' (Typed a_a9if) Type
+ Text.LLVM.Lens: typedTypeLens :: forall a_i4auw. Lens' (Typed a_i4auw) Type
- Text.LLVM.Lens: typedValueLens :: forall a_a9if a_a2ZKH. Lens (Typed a_a9if) (Typed a_a2ZKH) a_a9if a_a2ZKH
+ Text.LLVM.Lens: typedValueLens :: forall a_i4auw a_a4kya. Lens (Typed a_i4auw) (Typed a_a4kya) a_i4auw a_a4kya
- Text.LLVM.PP: Config :: Bool -> Bool -> Bool -> Config
+ Text.LLVM.PP: Config :: LLVMVer -> Config
- Text.LLVM.PP: angles :: Doc -> Doc
+ Text.LLVM.PP: angles :: Fmt Doc
- Text.LLVM.PP: commas :: [Doc] -> Doc
+ Text.LLVM.PP: commas :: Fmt [Doc]
- Text.LLVM.PP: hex :: (Integral i, Show i) => i -> Doc
+ Text.LLVM.PP: hex :: (Integral i, Show i) => Fmt i
- Text.LLVM.PP: integral :: Integral i => i -> Doc
+ Text.LLVM.PP: integral :: Integral i => Fmt i
- Text.LLVM.PP: mcommas :: [Maybe Doc] -> Doc
+ Text.LLVM.PP: mcommas :: Fmt [Maybe Doc]
- Text.LLVM.PP: opt :: Bool -> Doc -> Doc
+ Text.LLVM.PP: opt :: Bool -> Fmt Doc
- Text.LLVM.PP: ppAlign :: Maybe Align -> Doc
+ Text.LLVM.PP: ppAlign :: Fmt (Maybe Align)
- Text.LLVM.PP: ppAlloca :: LLVM => Type -> Maybe (Typed Value) -> Maybe Int -> Doc
+ Text.LLVM.PP: ppAlloca :: Type -> Maybe (Typed Value) -> Fmt (Maybe Int)
- Text.LLVM.PP: ppArgList :: Bool -> [Doc] -> Doc
+ Text.LLVM.PP: ppArgList :: Bool -> Fmt [Doc]
- Text.LLVM.PP: ppArithOp :: ArithOp -> Doc
+ Text.LLVM.PP: ppArithOp :: Fmt ArithOp
- Text.LLVM.PP: ppAsm :: Bool -> Bool -> String -> String -> Doc
+ Text.LLVM.PP: ppAsm :: Bool -> Bool -> String -> Fmt String
- Text.LLVM.PP: ppAtomicOp :: AtomicRWOp -> Doc
+ Text.LLVM.PP: ppAtomicOp :: Fmt AtomicRWOp
- Text.LLVM.PP: ppAtomicOrdering :: AtomicOrdering -> Doc
+ Text.LLVM.PP: ppAtomicOrdering :: Fmt AtomicOrdering
- Text.LLVM.PP: ppAttachedMetadata :: LLVM => [(String, ValMd)] -> Doc
+ Text.LLVM.PP: ppAttachedMetadata :: Fmt [(String, ValMd)]
- Text.LLVM.PP: ppBasicBlock :: LLVM => BasicBlock -> Doc
+ Text.LLVM.PP: ppBasicBlock :: Fmt BasicBlock
- Text.LLVM.PP: ppBitOp :: BitOp -> Doc
+ Text.LLVM.PP: ppBitOp :: Fmt BitOp
- Text.LLVM.PP: ppBool :: Bool -> Doc
+ Text.LLVM.PP: ppBool :: Fmt Bool
- Text.LLVM.PP: ppCall :: LLVM => Bool -> Type -> Value -> [Typed Value] -> Doc
+ Text.LLVM.PP: ppCall :: Bool -> Type -> Value -> Fmt [Typed Value]
- Text.LLVM.PP: ppCallSym :: LLVM => Type -> Value -> Doc
+ Text.LLVM.PP: ppCallSym :: Type -> Fmt Value
- Text.LLVM.PP: ppClause :: LLVM => Clause -> Doc
+ Text.LLVM.PP: ppClause :: Fmt Clause
- Text.LLVM.PP: ppClauses :: LLVM => Bool -> [Clause] -> Doc
+ Text.LLVM.PP: ppClauses :: Bool -> Fmt [Clause]
- Text.LLVM.PP: ppComdat :: (String, SelectionKind) -> Doc
+ Text.LLVM.PP: ppComdat :: Fmt (String, SelectionKind)
- Text.LLVM.PP: ppComdatName :: String -> Doc
+ Text.LLVM.PP: ppComdatName :: Fmt String
- Text.LLVM.PP: ppConstExpr :: LLVM => ConstExpr -> Doc
+ Text.LLVM.PP: ppConstExpr :: Fmt ConstExpr
- Text.LLVM.PP: ppConstExpr' :: LLVM => (i -> Doc) -> ConstExpr' i -> Doc
+ Text.LLVM.PP: ppConstExpr' :: Fmt i -> Fmt (ConstExpr' i)
- Text.LLVM.PP: ppConvOp :: ConvOp -> Doc
+ Text.LLVM.PP: ppConvOp :: Fmt ConvOp
- Text.LLVM.PP: ppDIBasicType :: DIBasicType -> Doc
+ Text.LLVM.PP: ppDIBasicType :: Fmt DIBasicType
- Text.LLVM.PP: ppDICompileUnit :: LLVM => DICompileUnit -> Doc
+ Text.LLVM.PP: ppDICompileUnit :: Fmt DICompileUnit
- Text.LLVM.PP: ppDICompileUnit' :: LLVM => (i -> Doc) -> DICompileUnit' i -> Doc
+ Text.LLVM.PP: ppDICompileUnit' :: Fmt i -> Fmt (DICompileUnit' i)
- Text.LLVM.PP: ppDICompositeType :: LLVM => DICompositeType -> Doc
+ Text.LLVM.PP: ppDICompositeType :: Fmt DICompositeType
- Text.LLVM.PP: ppDICompositeType' :: LLVM => (i -> Doc) -> DICompositeType' i -> Doc
+ Text.LLVM.PP: ppDICompositeType' :: Fmt i -> Fmt (DICompositeType' i)
- Text.LLVM.PP: ppDIDerivedType :: LLVM => DIDerivedType -> Doc
+ Text.LLVM.PP: ppDIDerivedType :: Fmt DIDerivedType
- Text.LLVM.PP: ppDIDerivedType' :: LLVM => (i -> Doc) -> DIDerivedType' i -> Doc
+ Text.LLVM.PP: ppDIDerivedType' :: Fmt i -> Fmt (DIDerivedType' i)
- Text.LLVM.PP: ppDIEnumerator :: String -> Int64 -> Doc
+ Text.LLVM.PP: ppDIEnumerator :: String -> Integer -> Fmt Bool
- Text.LLVM.PP: ppDIExpression :: DIExpression -> Doc
+ Text.LLVM.PP: ppDIExpression :: Fmt DIExpression
- Text.LLVM.PP: ppDIFile :: DIFile -> Doc
+ Text.LLVM.PP: ppDIFile :: Fmt DIFile
- Text.LLVM.PP: ppDIGlobalVariable :: LLVM => DIGlobalVariable -> Doc
+ Text.LLVM.PP: ppDIGlobalVariable :: Fmt DIGlobalVariable
- Text.LLVM.PP: ppDIGlobalVariable' :: LLVM => (i -> Doc) -> DIGlobalVariable' i -> Doc
+ Text.LLVM.PP: ppDIGlobalVariable' :: Fmt i -> Fmt (DIGlobalVariable' i)
- Text.LLVM.PP: ppDIGlobalVariableExpression :: LLVM => DIGlobalVariableExpression -> Doc
+ Text.LLVM.PP: ppDIGlobalVariableExpression :: Fmt DIGlobalVariableExpression
- Text.LLVM.PP: ppDIGlobalVariableExpression' :: LLVM => (i -> Doc) -> DIGlobalVariableExpression' i -> Doc
+ Text.LLVM.PP: ppDIGlobalVariableExpression' :: Fmt i -> Fmt (DIGlobalVariableExpression' i)
- Text.LLVM.PP: ppDIImportedEntity :: LLVM => DIImportedEntity -> Doc
+ Text.LLVM.PP: ppDIImportedEntity :: Fmt DIImportedEntity
- Text.LLVM.PP: ppDIImportedEntity' :: LLVM => (i -> Doc) -> DIImportedEntity' i -> Doc
+ Text.LLVM.PP: ppDIImportedEntity' :: Fmt i -> Fmt (DIImportedEntity' i)
- Text.LLVM.PP: ppDILabel :: LLVM => DILabel -> Doc
+ Text.LLVM.PP: ppDILabel :: Fmt DILabel
- Text.LLVM.PP: ppDILabel' :: LLVM => (i -> Doc) -> DILabel' i -> Doc
+ Text.LLVM.PP: ppDILabel' :: Fmt i -> Fmt (DILabel' i)
- Text.LLVM.PP: ppDILexicalBlock :: LLVM => DILexicalBlock -> Doc
+ Text.LLVM.PP: ppDILexicalBlock :: Fmt DILexicalBlock
- Text.LLVM.PP: ppDILexicalBlock' :: LLVM => (i -> Doc) -> DILexicalBlock' i -> Doc
+ Text.LLVM.PP: ppDILexicalBlock' :: Fmt i -> Fmt (DILexicalBlock' i)
- Text.LLVM.PP: ppDILexicalBlockFile :: LLVM => DILexicalBlockFile -> Doc
+ Text.LLVM.PP: ppDILexicalBlockFile :: Fmt DILexicalBlockFile
- Text.LLVM.PP: ppDILexicalBlockFile' :: LLVM => (i -> Doc) -> DILexicalBlockFile' i -> Doc
+ Text.LLVM.PP: ppDILexicalBlockFile' :: Fmt i -> Fmt (DILexicalBlockFile' i)
- Text.LLVM.PP: ppDILocalVariable :: LLVM => DILocalVariable -> Doc
+ Text.LLVM.PP: ppDILocalVariable :: Fmt DILocalVariable
- Text.LLVM.PP: ppDILocalVariable' :: LLVM => (i -> Doc) -> DILocalVariable' i -> Doc
+ Text.LLVM.PP: ppDILocalVariable' :: Fmt i -> Fmt (DILocalVariable' i)
- Text.LLVM.PP: ppDINameSpace :: LLVM => DINameSpace -> Doc
+ Text.LLVM.PP: ppDINameSpace :: Fmt DINameSpace
- Text.LLVM.PP: ppDINameSpace' :: LLVM => (i -> Doc) -> DINameSpace' i -> Doc
+ Text.LLVM.PP: ppDINameSpace' :: Fmt i -> Fmt (DINameSpace' i)
- Text.LLVM.PP: ppDISubprogram :: LLVM => DISubprogram -> Doc
+ Text.LLVM.PP: ppDISubprogram :: Fmt DISubprogram
- Text.LLVM.PP: ppDISubprogram' :: LLVM => (i -> Doc) -> DISubprogram' i -> Doc
+ Text.LLVM.PP: ppDISubprogram' :: Fmt i -> Fmt (DISubprogram' i)
- Text.LLVM.PP: ppDISubrange :: DISubrange -> Doc
+ Text.LLVM.PP: ppDISubrange :: Fmt DISubrange
- Text.LLVM.PP: ppDISubroutineType :: LLVM => DISubroutineType -> Doc
+ Text.LLVM.PP: ppDISubroutineType :: Fmt DISubroutineType
- Text.LLVM.PP: ppDISubroutineType' :: LLVM => (i -> Doc) -> DISubroutineType' i -> Doc
+ Text.LLVM.PP: ppDISubroutineType' :: Fmt i -> Fmt (DISubroutineType' i)
- Text.LLVM.PP: ppDITemplateTypeParameter :: LLVM => DITemplateTypeParameter -> Doc
+ Text.LLVM.PP: ppDITemplateTypeParameter :: Fmt DITemplateTypeParameter
- Text.LLVM.PP: ppDITemplateTypeParameter' :: LLVM => (i -> Doc) -> DITemplateTypeParameter' i -> Doc
+ Text.LLVM.PP: ppDITemplateTypeParameter' :: Fmt i -> Fmt (DITemplateTypeParameter' i)
- Text.LLVM.PP: ppDITemplateValueParameter :: LLVM => DITemplateValueParameter -> Doc
+ Text.LLVM.PP: ppDITemplateValueParameter :: Fmt DITemplateValueParameter
- Text.LLVM.PP: ppDITemplateValueParameter' :: LLVM => (i -> Doc) -> DITemplateValueParameter' i -> Doc
+ Text.LLVM.PP: ppDITemplateValueParameter' :: Fmt i -> Fmt (DITemplateValueParameter' i)
- Text.LLVM.PP: ppDataLayout :: DataLayout -> Doc
+ Text.LLVM.PP: ppDataLayout :: Fmt DataLayout
- Text.LLVM.PP: ppDebugInfo :: LLVM => DebugInfo -> Doc
+ Text.LLVM.PP: ppDebugInfo :: Fmt DebugInfo
- Text.LLVM.PP: ppDebugInfo' :: LLVM => (i -> Doc) -> DebugInfo' i -> Doc
+ Text.LLVM.PP: ppDebugInfo' :: Fmt i -> Fmt (DebugInfo' i)
- Text.LLVM.PP: ppDebugLoc :: LLVM => DebugLoc -> Doc
+ Text.LLVM.PP: ppDebugLoc :: Fmt DebugLoc
- Text.LLVM.PP: ppDebugLoc' :: LLVM => (i -> Doc) -> DebugLoc' i -> Doc
+ Text.LLVM.PP: ppDebugLoc' :: Fmt i -> Fmt (DebugLoc' i)
- Text.LLVM.PP: ppDeclare :: Declare -> Doc
+ Text.LLVM.PP: ppDeclare :: Fmt Declare
- Text.LLVM.PP: ppDefine :: LLVM => Define -> Doc
+ Text.LLVM.PP: ppDefine :: Fmt Define
- Text.LLVM.PP: ppExact :: Bool -> Doc
+ Text.LLVM.PP: ppExact :: Fmt Bool
- Text.LLVM.PP: ppFCmpOp :: FCmpOp -> Doc
+ Text.LLVM.PP: ppFCmpOp :: Fmt FCmpOp
- Text.LLVM.PP: ppFlags :: Maybe String -> Doc
+ Text.LLVM.PP: ppFlags :: Fmt (Maybe String)
- Text.LLVM.PP: ppFloatType :: FloatType -> Doc
+ Text.LLVM.PP: ppFloatType :: Fmt FloatType
- Text.LLVM.PP: ppFunAttr :: FunAttr -> Doc
+ Text.LLVM.PP: ppFunAttr :: Fmt FunAttr
- Text.LLVM.PP: ppGC :: GC -> Doc
+ Text.LLVM.PP: ppGC :: Fmt GC
- Text.LLVM.PP: ppGEP :: LLVM => Bool -> Typed Value -> [Typed Value] -> Doc
+ Text.LLVM.PP: ppGEP :: Bool -> Type -> Typed Value -> Fmt [Typed Value]
- Text.LLVM.PP: ppGlobal :: LLVM => Global -> Doc
+ Text.LLVM.PP: ppGlobal :: Fmt Global
- Text.LLVM.PP: ppGlobalAlias :: LLVM => GlobalAlias -> Doc
+ Text.LLVM.PP: ppGlobalAlias :: Fmt GlobalAlias
- Text.LLVM.PP: ppGlobalAttrs :: GlobalAttrs -> Doc
+ Text.LLVM.PP: ppGlobalAttrs :: Bool -> Fmt GlobalAttrs
- Text.LLVM.PP: ppICmpOp :: ICmpOp -> Doc
+ Text.LLVM.PP: ppICmpOp :: Fmt ICmpOp
- Text.LLVM.PP: ppIdent :: Ident -> Doc
+ Text.LLVM.PP: ppIdent :: Fmt Ident
- Text.LLVM.PP: ppInlineAsm :: InlineAsm -> Doc
+ Text.LLVM.PP: ppInlineAsm :: Fmt InlineAsm
- Text.LLVM.PP: ppInstr :: LLVM => Instr -> Doc
+ Text.LLVM.PP: ppInstr :: Fmt Instr
- Text.LLVM.PP: ppInvoke :: LLVM => Type -> Value -> [Typed Value] -> BlockLabel -> BlockLabel -> Doc
+ Text.LLVM.PP: ppInvoke :: Type -> Value -> [Typed Value] -> BlockLabel -> Fmt BlockLabel
- Text.LLVM.PP: ppLLVM :: (LLVM => a) -> a
+ Text.LLVM.PP: ppLLVM :: LLVMVer -> ((?config :: Config) => a) -> a
- Text.LLVM.PP: ppLLVM35 :: (LLVM => a) -> a
+ Text.LLVM.PP: ppLLVM35 :: ((?config :: Config) => a) -> a
- Text.LLVM.PP: ppLLVM36 :: (LLVM => a) -> a
+ Text.LLVM.PP: ppLLVM36 :: ((?config :: Config) => a) -> a
- Text.LLVM.PP: ppLLVM37 :: (LLVM => a) -> a
+ Text.LLVM.PP: ppLLVM37 :: ((?config :: Config) => a) -> a
- Text.LLVM.PP: ppLLVM38 :: (LLVM => a) -> a
+ Text.LLVM.PP: ppLLVM38 :: ((?config :: Config) => a) -> a
- Text.LLVM.PP: ppLabel :: BlockLabel -> Doc
+ Text.LLVM.PP: ppLabel :: Fmt BlockLabel
- Text.LLVM.PP: ppLabelDef :: BlockLabel -> Doc
+ Text.LLVM.PP: ppLabelDef :: Fmt BlockLabel
- Text.LLVM.PP: ppLayoutBody :: Int -> Int -> Maybe Int -> Doc
+ Text.LLVM.PP: ppLayoutBody :: Int -> Int -> Fmt (Maybe Int)
- Text.LLVM.PP: ppLayoutSpec :: LayoutSpec -> Doc
+ Text.LLVM.PP: ppLayoutSpec :: Fmt LayoutSpec
- Text.LLVM.PP: ppLinkage :: Linkage -> Doc
+ Text.LLVM.PP: ppLinkage :: Fmt Linkage
- Text.LLVM.PP: ppLoad :: LLVM => Typed (Value' BlockLabel) -> Maybe AtomicOrdering -> Maybe Align -> Doc
+ Text.LLVM.PP: ppLoad :: Type -> Typed (Value' BlockLabel) -> Maybe AtomicOrdering -> Fmt (Maybe Align)
- Text.LLVM.PP: ppMangling :: Mangling -> Doc
+ Text.LLVM.PP: ppMangling :: Fmt Mangling
- Text.LLVM.PP: ppMaybe :: (a -> Doc) -> Maybe a -> Doc
+ Text.LLVM.PP: ppMaybe :: Fmt a -> Fmt (Maybe a)
- Text.LLVM.PP: ppMetadata :: Doc -> Doc
+ Text.LLVM.PP: ppMetadata :: Fmt Doc
- Text.LLVM.PP: ppMetadataNode :: LLVM => [Maybe ValMd] -> Doc
+ Text.LLVM.PP: ppMetadataNode :: Fmt [Maybe ValMd]
- Text.LLVM.PP: ppMetadataNode' :: LLVM => (i -> Doc) -> [Maybe (ValMd' i)] -> Doc
+ Text.LLVM.PP: ppMetadataNode' :: Fmt i -> Fmt [Maybe (ValMd' i)]
- Text.LLVM.PP: ppModule :: LLVM => Module -> Doc
+ Text.LLVM.PP: ppModule :: Fmt Module
- Text.LLVM.PP: ppNamedMd :: NamedMd -> Doc
+ Text.LLVM.PP: ppNamedMd :: Fmt NamedMd
- Text.LLVM.PP: ppPhiArg :: LLVM => (Value, BlockLabel) -> Doc
+ Text.LLVM.PP: ppPhiArg :: Fmt (Value, BlockLabel)
- Text.LLVM.PP: ppPrimType :: PrimType -> Doc
+ Text.LLVM.PP: ppPrimType :: Fmt PrimType
- Text.LLVM.PP: ppScope :: Maybe String -> Doc
+ Text.LLVM.PP: ppScope :: Fmt (Maybe String)
- Text.LLVM.PP: ppSelectionKind :: SelectionKind -> Doc
+ Text.LLVM.PP: ppSelectionKind :: Fmt SelectionKind
- Text.LLVM.PP: ppSignBits :: Bool -> Bool -> Doc
+ Text.LLVM.PP: ppSignBits :: Bool -> Fmt Bool
- Text.LLVM.PP: ppSourceName :: Maybe String -> Doc
+ Text.LLVM.PP: ppSourceName :: Fmt (Maybe String)
- Text.LLVM.PP: ppStmt :: LLVM => Stmt -> Doc
+ Text.LLVM.PP: ppStmt :: Fmt Stmt
- Text.LLVM.PP: ppStore :: LLVM => Typed (Value' BlockLabel) -> Typed (Value' BlockLabel) -> Maybe AtomicOrdering -> Maybe Align -> Doc
+ Text.LLVM.PP: ppStore :: Typed (Value' BlockLabel) -> Typed (Value' BlockLabel) -> Maybe AtomicOrdering -> Fmt (Maybe Align)
- Text.LLVM.PP: ppStringLiteral :: String -> Doc
+ Text.LLVM.PP: ppStringLiteral :: Fmt String
- Text.LLVM.PP: ppSwitchEntry :: Type -> (Integer, BlockLabel) -> Doc
+ Text.LLVM.PP: ppSwitchEntry :: Type -> Fmt (Integer, BlockLabel)
- Text.LLVM.PP: ppSymbol :: Symbol -> Doc
+ Text.LLVM.PP: ppSymbol :: Fmt Symbol
- Text.LLVM.PP: ppType :: Type -> Doc
+ Text.LLVM.PP: ppType :: Fmt Type
- Text.LLVM.PP: ppTypeDecl :: TypeDecl -> Doc
+ Text.LLVM.PP: ppTypeDecl :: Fmt TypeDecl
- Text.LLVM.PP: ppTyped :: (a -> Doc) -> Typed a -> Doc
+ Text.LLVM.PP: ppTyped :: Fmt a -> Fmt (Typed a)
- Text.LLVM.PP: ppTypedLabel :: BlockLabel -> Doc
+ Text.LLVM.PP: ppTypedLabel :: Fmt BlockLabel
- Text.LLVM.PP: ppTypedValMd :: LLVM => ValMd -> Doc
+ Text.LLVM.PP: ppTypedValMd :: Fmt ValMd
- Text.LLVM.PP: ppUnnamedMd :: LLVM => UnnamedMd -> Doc
+ Text.LLVM.PP: ppUnnamedMd :: Fmt UnnamedMd
- Text.LLVM.PP: ppValMd :: LLVM => ValMd -> Doc
+ Text.LLVM.PP: ppValMd :: Fmt ValMd
- Text.LLVM.PP: ppValMd' :: LLVM => (i -> Doc) -> ValMd' i -> Doc
+ Text.LLVM.PP: ppValMd' :: Fmt i -> Fmt (ValMd' i)
- Text.LLVM.PP: ppValue :: LLVM => Value -> Doc
+ Text.LLVM.PP: ppValue :: Fmt Value
- Text.LLVM.PP: ppValue' :: LLVM => (i -> Doc) -> Value' i -> Doc
+ Text.LLVM.PP: ppValue' :: Fmt i -> Fmt (Value' i)
- Text.LLVM.PP: ppVectorIndex :: LLVM => Value -> Doc
+ Text.LLVM.PP: ppVectorIndex :: Fmt Value
- Text.LLVM.PP: ppVisibility :: Visibility -> Doc
+ Text.LLVM.PP: ppVisibility :: Fmt Visibility
- Text.LLVM.PP: structBraces :: Doc -> Doc
+ Text.LLVM.PP: structBraces :: Fmt Doc
- Text.LLVM.PP: withConfig :: Config -> (LLVM => a) -> a
+ Text.LLVM.PP: withConfig :: Config -> ((?config :: Config) => a) -> a
Files
- CHANGELOG.md +5/−0
- README.md +36/−0
- llvm-pretty.cabal +40/−9
- src/Text/LLVM.hs +41/−48
- src/Text/LLVM/AST.hs +457/−68
- src/Text/LLVM/DebugUtils.hs +227/−45
- src/Text/LLVM/Labels.hs +17/−14
- src/Text/LLVM/Lens.hs +2/−1
- src/Text/LLVM/PP.hs +407/−230
- src/Text/LLVM/Parser.hs +1/−0
- src/Text/LLVM/Triple.hs +17/−0
- src/Text/LLVM/Triple/AST.hs +467/−0
- src/Text/LLVM/Triple/Parse.hs +294/−0
- src/Text/LLVM/Triple/Parse/ARM.hs +347/−0
- src/Text/LLVM/Triple/Parse/LookupTable.hs +77/−0
- src/Text/LLVM/Triple/Print.hs +229/−0
- test/Main.hs +13/−0
- test/Output.hs +302/−0
- test/TQQDefs.hs +62/−0
- test/Triple.hs +72/−0
+ CHANGELOG.md view
@@ -0,0 +1,5 @@+# Revision history for llvm-pretty++## 0.12.0.0 (January 2024)++* Add preliminary support for LLVM versions up through 17.
+ README.md view
@@ -0,0 +1,36 @@+# `llvm-pretty`++A pretty printing library that was inspired by the LLVM binding by Lennart+Augustsson. The library provides a monadic interface to a pretty printer, that+allows functions to be defined and called, generating the corresponding LLVM+assembly when run.++## LLVM language feature support++Currently, `llvm-pretty` supports LLVM versions up through 17. As a result of+the broad version coverage, the `llvm-pretty` AST is a superset of all versions+of the LLVM AST. This means that the manner in which certain information is+presented in the `llvm-pretty` AST (e.g., during pretty printing) will be+different depending on the LLVM version used to originate the information.+Conversely, it is possible to construct an `llvm-pretty` AST that cannot be+represented in a specific (or any) LLVM version.++`llvm-pretty` strives to support a reasonable variety of [LLVM language+features](https://llvm.org/docs/LangRef.html), but there are places where our+coverage of the LLVM language is incomplete. If you need a LLVM feature that is+not currently supported by `llvm-pretty`, please [file an+issue](https://github.com/elliottt/llvm-pretty/issues/new).++## `llvm-pretty` versus `llvm-pretty-bc-parser`++`llvm-pretty` supports almost everything that one would want to do with LLVM+ASTs. One notable exception is parsing: `llvm-pretty` deliberately does not+support parsing an LLVM module AST from a bitcode file. This functionality is+factored out into a separate+[`llvm-pretty-bc-parser`](https://github.com/GaloisInc/llvm-pretty-bc-parser)+library. `llvm-pretty-bc-parser` generally tries to stay in sync with all of+the LLVM language features that `llvm-pretty` supports, but it may be the case+that some valid `llvm-pretty` ASTs cannot be parsed by `llvm-pretty-bc-parser`.+If you encounter an occurrence of this issue, please [file an+issue](https://github.com/GaloisInc/llvm-pretty-bc-parser/issues/new) at the+`llvm-pretty-bc-parser` issue tracker.
llvm-pretty.cabal view
@@ -1,12 +1,12 @@+Cabal-version: 2.2 Name: llvm-pretty-Version: 0.11.0-License: BSD3+Version: 0.12.0.0+License: BSD-3-Clause License-file: LICENSE Author: Trevor Elliott-Maintainer: awesomelyawesome@gmail.com+Maintainer: rscott@galois.com, kquick@galois.com Category: Text Build-type: Simple-Cabal-version: >=1.16 Synopsis: A pretty printing library inspired by the llvm binding. Description: A pretty printing library that was inspired by the LLVM binding by Lennart@@ -14,15 +14,21 @@ that allows functions to be defined and called, generating the corresponding LLVM assembly when run. tested-with: GHC==8.4.3, GHC==8.2.2, GHC==8.0.2+extra-doc-files: CHANGELOG.md, README.md source-repository head type: git location: http://github.com/elliottt/llvm-pretty -Library+common common Default-language: Haskell2010+ Ghc-options:+ -Wall +Library+ Import: common+ Hs-source-dirs: src Exposed-modules: Text.LLVM Text.LLVM.AST@@ -32,16 +38,41 @@ Text.LLVM.Parser Text.LLVM.PP Text.LLVM.DebugUtils- Other-modules: Text.LLVM.Util+ Text.LLVM.Triple+ Text.LLVM.Triple.AST+ Text.LLVM.Triple.Parse+ Text.LLVM.Triple.Print+ Other-modules: Text.LLVM.Triple.Parse.ARM+ Text.LLVM.Triple.Parse.LookupTable+ Text.LLVM.Util - Build-depends: base >= 4 && < 5,+ Build-depends: base >= 4.9 && < 5, containers >= 0.4, parsec >= 3, pretty >= 1.0.1, monadLib >= 3.6.1, microlens >= 0.4, microlens-th >= 0.4,+ syb >= 0.7, template-haskell >= 2.7,- th-abstraction >= 0.3.1 && <0.4+ th-abstraction >= 0.3.1 && <0.7 - Ghc-options: -Wall+Test-suite llvm-pretty-test+ Import: common+ Type: exitcode-stdio-1.0+ Main-is: Main.hs+ Other-modules:+ Output+ Triple+ TQQDefs+ Hs-source-dirs: test+ Ghc-options:+ -threaded+ Build-depends:+ llvm-pretty,+ base,+ pretty,+ tasty,+ tasty-hunit,+ template-haskell,+ text
src/Text/LLVM.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE CPP #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE RecursiveDo #-} {-# LANGUAGE TypeOperators #-}@@ -7,11 +6,6 @@ {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE TypeSynonymInstances #-}--#ifndef MIN_VERSION_base-#define MIN_VERSION_base(x,y,z) 1-#endif- module Text.LLVM ( -- * LLVM Monad LLVM()@@ -120,11 +114,7 @@ import qualified Data.Sequence as Seq import qualified Data.Map.Strict as Map -#if !(MIN_VERSION_base(4,8,0))-import Control.Applicative ( Applicative )-#endif - -- Fresh Names ----------------------------------------------------------------- type Names = Map.Map String Int@@ -189,12 +179,14 @@ -- | Emit a declaration. declare :: Type -> Symbol -> [Type] -> Bool -> LLVM (Typed Value) declare rty sym tys va = emitDeclare Declare- { decRetType = rty- , decName = sym- , decArgs = tys- , decVarArgs = va- , decAttrs = []- , decComdat = Nothing+ { decLinkage = Nothing+ , decVisibility = Nothing+ , decRetType = rty+ , decName = sym+ , decArgs = tys+ , decVarArgs = va+ , decAttrs = []+ , decComdat = Nothing } -- | Emit a global declaration.@@ -222,14 +214,16 @@ -- Function Definition --------------------------------------------------------- data FunAttrs = FunAttrs- { funLinkage :: Maybe Linkage- , funGC :: Maybe GC+ { funLinkage :: Maybe Linkage+ , funVisibility :: Maybe Visibility+ , funGC :: Maybe GC } deriving (Show) emptyFunAttrs :: FunAttrs emptyFunAttrs = FunAttrs- { funLinkage = Nothing- , funGC = Nothing+ { funLinkage = Nothing+ , funVisibility = Nothing+ , funGC = Nothing } @@ -273,17 +267,18 @@ define attrs rty fun sig k = do (args,body) <- defineBody [] sig k emitDefine Define- { defLinkage = funLinkage attrs- , defName = fun- , defRetType = rty- , defArgs = args- , defVarArgs = False- , defAttrs = []- , defSection = Nothing- , defGC = funGC attrs- , defBody = body- , defMetadata = Map.empty- , defComdat = Nothing+ { defLinkage = funLinkage attrs+ , defVisibility = funVisibility attrs+ , defName = fun+ , defRetType = rty+ , defArgs = args+ , defVarArgs = False+ , defAttrs = []+ , defSection = Nothing+ , defGC = funGC attrs+ , defBody = body+ , defMetadata = Map.empty+ , defComdat = Nothing } -- | A combination of define and @freshSymbol@.@@ -301,17 +296,18 @@ define' attrs rty sym sig va k = do args <- mapM freshArg sig emitDefine Define- { defLinkage = funLinkage attrs- , defName = sym- , defRetType = rty- , defArgs = args- , defVarArgs = va- , defAttrs = []- , defSection = Nothing- , defGC = funGC attrs- , defBody = snd (runBB (k (map (fmap toValue) args)))- , defMetadata = Map.empty- , defComdat = Nothing+ { defLinkage = funLinkage attrs+ , defVisibility = funVisibility attrs+ , defName = sym+ , defRetType = rty+ , defArgs = args+ , defVarArgs = va+ , defAttrs = []+ , defSection = Nothing+ , defGC = funGC attrs+ , defBody = snd (runBB (k (map (fmap toValue) args)))+ , defMetadata = Map.empty+ , defComdat = Nothing } -- Basic Block Monad -----------------------------------------------------------@@ -626,11 +622,8 @@ where es = fmap toValue `fmap` mb -load :: IsValue a => Typed a -> Maybe Align -> BB (Typed Value)-load tv ma =- case typedType tv of- PtrTo ty -> observe ty (Load (toValue `fmap` tv) Nothing ma)- _ -> error "load not given a pointer"+load :: IsValue a => Type -> Typed a -> Maybe Align -> BB (Typed Value)+load ty ptr ma = observe ty (Load ty (toValue `fmap` ptr) Nothing ma) store :: (IsValue a, IsValue b) => a -> Typed b -> Maybe Align -> BB () store a ptr ma =@@ -702,7 +695,7 @@ getelementptr :: IsValue a => Type -> Typed a -> [Typed Value] -> BB (Typed Value)-getelementptr ty ptr ixs = observe ty (GEP False (toValue `fmap` ptr) ixs)+getelementptr ty ptr ixs = observe ty (GEP False ty (toValue `fmap` ptr) ixs) -- | Emit a call instruction, and generate a new variable for its result. call :: IsValue a => Typed a -> [Typed Value] -> BB (Typed Value)
src/Text/LLVM/AST.hs view
@@ -1,15 +1,165 @@-{-# LANGUAGE CPP #-} {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE DeriveDataTypeable, DeriveFunctor, DeriveGeneric #-} {-# LANGUAGE PatternGuards #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE DeriveGeneric #-}--#ifndef MIN_VERSION_base-#define MIN_VERSION_base(x,y,z) 1-#endif--module Text.LLVM.AST where+{-# LANGUAGE DeriveLift #-}+module Text.LLVM.AST+ ( -- * Modules+ Module(..)+ , emptyModule+ -- * Named Metadata+ , NamedMd(..)+ -- * Unnamed Metadata+ , UnnamedMd(..)+ -- * Aliases+ , GlobalAlias(..)+ -- * Data Layout+ , DataLayout+ , LayoutSpec(..)+ , Mangling(..)+ , parseDataLayout+ -- * Inline Assembly+ , InlineAsm+ -- * Comdat+ , SelectionKind(..)+ -- * Identifiers+ , Ident(..)+ -- * Symbols+ , Symbol(..)+ -- * Types+ , PrimType(..)+ , FloatType(..)+ , Type, Type'(..)+ , updateAliasesA, updateAliases+ , isFloatingPoint+ , isAlias+ , isPrimTypeOf+ , isLabel+ , isInteger+ , isVector+ , isVectorOf+ , isArray+ , isPointer+ , eqTypeModuloOpaquePtrs+ , cmpTypeModuloOpaquePtrs+ , fixupOpaquePtrs+ -- * Null values+ , NullResult(..)+ , primTypeNull+ , floatTypeNull+ , typeNull+ -- * Type Elimination+ , elimFunTy+ , elimAlias+ , elimPtrTo+ , elimVector+ , elimArray+ , elimFunPtr+ , elimPrimType+ , elimFloatType+ , elimSequentialType+ -- * Top-level Type Aliases+ , TypeDecl(..)+ -- * Globals+ , Global(..)+ , addGlobal+ , GlobalAttrs(..)+ , emptyGlobalAttrs+ -- * Declarations+ , Declare(..)+ , decFunType+ -- * Function Definitions+ , Define(..)+ , defFunType, addDefine+ -- * Function Attributes and attribute groups+ , FunAttr(..)+ -- * Basic Block Labels+ , BlockLabel(..)+ -- * Basic Blocks+ , BasicBlock'(..), BasicBlock+ , brTargets+ -- * Attributes+ , Linkage(..)+ , Visibility(..)+ , GC(..)+ -- * Typed Things+ , Typed(..)+ , mapMTyped+ -- * Instructions+ , ArithOp(..)+ , isIArith+ , isFArith+ , UnaryArithOp(..)+ , BitOp(..)+ , ConvOp(..)+ , AtomicRWOp(..)+ , AtomicOrdering(..)+ , Align+ , Instr'(..), Instr+ , Clause'(..), Clause+ , isTerminator+ , isComment+ , isPhi+ , ICmpOp(..)+ , FCmpOp(..)+ -- * Values+ , Value'(..), Value+ , FP80Value(..)+ , ValMd'(..), ValMd+ , KindMd+ , FnMdAttachments+ , GlobalMdAttachments+ , DebugLoc'(..), DebugLoc+ , isConst+ -- * Value Elimination+ , elimValSymbol+ , elimValInteger+ -- * Statements+ , Stmt'(..), Stmt+ , stmtInstr+ , stmtMetadata+ , extendMetadata+ -- * Constant Expressions+ , ConstExpr'(..), ConstExpr+ -- * DWARF Debug Info+ , DebugInfo'(..), DebugInfo+ , DILabel, DILabel'(..)+ , DIImportedEntity, DIImportedEntity'(..)+ , DITemplateTypeParameter, DITemplateTypeParameter'(..)+ , DITemplateValueParameter, DITemplateValueParameter'(..)+ , DINameSpace, DINameSpace'(..)+ , DwarfAttrEncoding+ , DwarfLang+ , DwarfTag+ , DwarfVirtuality+ , DIFlags+ , DIEmissionKind+ , DIBasicType(..)+ , DICompileUnit'(..), DICompileUnit+ , DICompositeType'(..), DICompositeType+ , DIDerivedType'(..), DIDerivedType+ , DIExpression(..)+ , DIFile(..)+ , DIGlobalVariable'(..), DIGlobalVariable+ , DIGlobalVariableExpression'(..), DIGlobalVariableExpression+ , DILexicalBlock'(..), DILexicalBlock+ , DILexicalBlockFile'(..), DILexicalBlockFile+ , DILocalVariable'(..), DILocalVariable+ , DISubprogram'(..), DISubprogram+ , DISubrange'(..), DISubrange+ , DISubroutineType'(..), DISubroutineType+ , DIArgList'(..), DIArgList+ -- * Aggregate Utilities+ , IndexResult(..)+ , isInvalid+ , resolveGepFull+ , resolveGep+ , resolveGepBody+ , isGepIndex+ , isGepStructIndex+ , resolveValueIndex+ ) where import Data.Functor.Identity (Identity(..)) import Data.Coerce (coerce)@@ -17,28 +167,27 @@ import Data.Typeable (Typeable) import Control.Monad (MonadPlus(mzero,mplus),(<=<),guard) import Data.Int (Int32,Int64)+import Data.Generics (everywhere, extQ, mkT, something) import Data.List (genericIndex,genericLength) import qualified Data.Map as Map+import Data.Maybe (isJust) import Data.Semigroup as Sem import Data.String (IsString(fromString)) import Data.Word (Word8,Word16,Word32,Word64) import GHC.Generics (Generic, Generic1)+import Language.Haskell.TH.Syntax (Lift) import Text.Parsec import Text.Parsec.String -#if !(MIN_VERSION_base(4,8,0))-import Control.Applicative ((<$))-import Data.Foldable (Foldable(foldMap))-import Data.Monoid (Monoid(..))-import Data.Traversable (Traversable(sequenceA))-#endif+import Text.LLVM.Triple.AST (TargetTriple) -- Modules --------------------------------------------------------------------- data Module = Module { modSourceName :: Maybe String+ , modTriple :: TargetTriple -- ^ target triple , modDataLayout :: DataLayout -- ^ type size and alignment information , modTypes :: [TypeDecl] -- ^ top-level type aliases , modNamedMd :: [NamedMd]@@ -51,9 +200,11 @@ , modAliases :: [GlobalAlias] } deriving (Data, Eq, Ord, Generic, Show, Typeable) +-- | Combines fields pointwise. instance Sem.Semigroup Module where m1 <> m2 = Module { modSourceName = modSourceName m1 `mplus` modSourceName m2+ , modTriple = modTriple m1 <> modTriple m2 , modDataLayout = modDataLayout m1 <> modDataLayout m2 , modTypes = modTypes m1 <> modTypes m2 , modUnnamedMd = modUnnamedMd m1 <> modUnnamedMd m2@@ -68,11 +219,12 @@ instance Monoid Module where mempty = emptyModule- mappend m1 m2 = m1 <> m2+ mappend = (<>) emptyModule :: Module emptyModule = Module { modSourceName = mempty+ , modTriple = mempty , modDataLayout = mempty , modTypes = mempty , modNamedMd = mempty@@ -106,9 +258,11 @@ -- Aliases --------------------------------------------------------------------- data GlobalAlias = GlobalAlias- { aliasName :: Symbol- , aliasType :: Type- , aliasTarget :: Value+ { aliasLinkage :: Maybe Linkage+ , aliasVisibility :: Maybe Visibility+ , aliasName :: Symbol+ , aliasType :: Type+ , aliasTarget :: Value } deriving (Data, Eq, Generic, Ord, Show, Typeable) @@ -215,7 +369,7 @@ -- Identifiers ----------------------------------------------------------------- newtype Ident = Ident String- deriving (Data, Eq, Generic, Ord, Show, Typeable)+ deriving (Data, Eq, Generic, Ord, Show, Typeable, Lift) instance IsString Ident where fromString = Ident@@ -223,7 +377,7 @@ -- Symbols --------------------------------------------------------------------- newtype Symbol = Symbol String- deriving (Data, Eq, Generic, Ord, Show, Typeable)+ deriving (Data, Eq, Generic, Ord, Show, Typeable, Lift) instance Sem.Semigroup Symbol where Symbol a <> Symbol b = Symbol (a <> b)@@ -244,7 +398,7 @@ | FloatType FloatType | X86mmx | Metadata- deriving (Data, Eq, Generic, Ord, Show, Typeable)+ deriving (Data, Eq, Generic, Ord, Show, Typeable, Lift) data FloatType = Half@@ -253,7 +407,7 @@ | Fp128 | X86_fp80 | PPC_fp128- deriving (Data, Eq, Enum, Generic, Ord, Show, Typeable)+ deriving (Data, Eq, Enum, Generic, Ord, Show, Typeable, Lift) type Type = Type' Ident @@ -263,10 +417,32 @@ | Array Word64 (Type' ident) | FunTy (Type' ident) [Type' ident] Bool | PtrTo (Type' ident)+ -- ^ A pointer to a memory location of a particular type. See also+ -- 'PtrOpaque', which represents a pointer without a pointee type.+ --+ -- LLVM pointers can also have an optional address space attribute, but this+ -- is not currently represented in the @llvm-pretty@ AST.+ | PtrOpaque+ -- ^ A pointer to a memory location. Unlike 'PtrTo', a 'PtrOpaque' does not+ -- have a pointee type. Instead, instructions interacting through opaque+ -- pointers specify the type of the underlying memory they are interacting+ -- with.+ --+ -- LLVM pointers can also have an optional address space attribute, but this+ -- is not currently represented in the @llvm-pretty@ AST.+ --+ -- 'PtrOpaque' should not be confused with 'Opaque', which is a completely+ -- separate type with a similar-sounding name. | Struct [Type' ident] | PackedStruct [Type' ident] | Vector Word64 (Type' ident) | Opaque+ -- ^ An opaque structure type, used to represent structure types that do not+ -- have a body specified. This is similar to C's notion of a+ -- forward-declared structure.+ --+ -- 'Opaque' should not be confused with 'PtrOpaque', which is a completely+ -- separate type with a similar-sounding name. deriving (Data, Eq, Functor, Generic, Generic1, Ord, Show, Typeable) -- | Applicatively traverse a type, updating or removing aliases.@@ -277,6 +453,7 @@ Array len ety -> Array len <$> (loop ety) FunTy res ps var -> FunTy <$> (loop res) <*> (traverse loop ps) <*> pure var PtrTo pty -> PtrTo <$> (loop pty)+ PtrOpaque -> pure PtrOpaque Struct fs -> Struct <$> (traverse loop fs) PackedStruct fs -> PackedStruct <$> (traverse loop fs) Vector len ety -> Vector <$> pure len <*> (loop ety)@@ -323,9 +500,100 @@ isPointer :: Type -> Bool isPointer (PtrTo _) = True+isPointer PtrOpaque = True isPointer _ = False +-- | Like `Type'`, but where the 'PtrTo' and 'PtrOpaque' constructors have been+-- collapsed into a single 'PtrView' constructor. This provides a coarser notion+-- of type equality than what `Type'` provides, which distinguishes the two+-- types of pointers.+--+-- `TypeView'` is not used directly in any of the other AST types. Instead, it+-- is used only as an internal data type to power the 'eqTypeModuloOpaquePtrs'+-- and 'cmpTypeModuloOpaquePtrs' functions.+data TypeView' ident+ = PrimTypeView PrimType+ | AliasView ident+ | ArrayView Word64 (TypeView' ident)+ | FunTyView (TypeView' ident) [TypeView' ident] Bool+ | PtrView+ -- ^ The sole pointer type. Both 'PtrTo' and 'PtrOpaque' are mapped to+ -- 'PtrView'.+ | StructView [TypeView' ident]+ | PackedStructView [TypeView' ident]+ | VectorView Word64 (TypeView' ident)+ | OpaqueView+ -- ^ An opaque structure type, used to represent structure types that do not+ -- forward-declared structure.+ --+ -- 'OpaqueView' should not be confused with opaque pointers, which are+ -- mapped to 'PtrView'.+ deriving (Eq, Ord)++-- | Convert a `Type'` value to a `TypeView'` value.+typeView :: Type' ident -> TypeView' ident+-- The two most important cases. Both forms of pointers are mapped to PtrView.+typeView (PtrTo _) = PtrView+typeView PtrOpaque = PtrView+-- All other cases are straightforward.+typeView (PrimType pt) = PrimTypeView pt+typeView (Alias lab) = AliasView lab+typeView (Array len et) = ArrayView len (typeView et)+typeView (FunTy ret args va) = FunTyView (typeView ret) (map typeView args) va+typeView (Struct fs) = StructView (map typeView fs)+typeView (PackedStruct fs) = PackedStructView (map typeView fs)+typeView (Vector len et) = VectorView len (typeView et)+typeView Opaque = OpaqueView++-- | Check two 'Type's for equality, but treat 'PtrOpaque' types as being equal+-- to @'PtrTo' ty@ types (for any type @ty@). This is a coarser notion of+-- equality than what is provided by the 'Eq' instance for 'Type'.+eqTypeModuloOpaquePtrs :: Eq ident => Type' ident -> Type' ident -> Bool+eqTypeModuloOpaquePtrs x y = typeView x == typeView y++-- | Compare two 'Type's, but treat 'PtrOpaque' types as being equal to+-- @'PtrTo' ty@ types (for any type @ty@). This is a coarser notion of ordering+-- than what is provided by the 'Ord' instance for 'Type'.+cmpTypeModuloOpaquePtrs :: Ord ident => Type' ident -> Type' ident -> Ordering+cmpTypeModuloOpaquePtrs x y = typeView x `compare` typeView y++-- | Ensure that if there are any occurrences of opaque pointers, then all+-- non-opaque pointers are converted to opaque ones.+--+-- This is useful because LLVM tools like @llvm-as@ are stricter than+-- @llvm-pretty@ in that the former forbids mixing opaque and non-opaque+-- pointers, whereas the latter allows this. As a result, the result of+-- pretty-printing an @llvm-pretty@ AST might not be suitable for @llvm-as@'s+-- needs unless you first call this function to ensure that the two types of+-- pointers are not intermixed.+--+-- This is implemented using "Data.Data" combinators under the hood, which could+-- potentially require a full traversal of the AST. Because of the performance+-- implications of this, we do not call 'fixupOpaquePtrs' in @llvm-pretty@'s+-- pretty-printer. If you wish to combine opaque and non-opaque pointers in your+-- AST, the burden is on you to call this function before pretty-printing.+fixupOpaquePtrs :: Data a => a -> a+fixupOpaquePtrs m+ | isJust (gfind isOpaquePtr m)+ = everywhere (mkT opaquifyPtr) m+ | otherwise+ = m+ where+ isOpaquePtr :: Type -> Bool+ isOpaquePtr PtrOpaque = True+ isOpaquePtr _ = False++ opaquifyPtr :: Type -> Type+ opaquifyPtr (PtrTo _) = PtrOpaque+ opaquifyPtr t = t++ -- Find the first occurrence of a @b@ value within the @a@ value that+ -- satisfies the predicate and return it with 'Just'. Return 'Nothing' if there+ -- are no such occurrences.+ gfind :: (Data a, Typeable b) => (b -> Bool) -> a -> Maybe b+ gfind p = something (const Nothing `extQ` \x -> if p x then Just x else Nothing)+ -- Null Values ----------------------------------------------------------------- data NullResult lab@@ -348,6 +616,7 @@ typeNull :: Type -> NullResult lab typeNull (PrimType pt) = HasNull (primTypeNull pt) typeNull PtrTo{} = HasNull ValNull+typeNull PtrOpaque = HasNull ValNull typeNull (Alias i) = ResolveNull i typeNull _ = HasNull ValZeroInit @@ -432,12 +701,14 @@ -- Declarations ---------------------------------------------------------------- data Declare = Declare- { decRetType :: Type- , decName :: Symbol- , decArgs :: [Type]- , decVarArgs :: Bool- , decAttrs :: [FunAttr]- , decComdat :: Maybe String+ { decLinkage :: Maybe Linkage+ , decVisibility :: Maybe Visibility+ , decRetType :: Type+ , decName :: Symbol+ , decArgs :: [Type]+ , decVarArgs :: Bool+ , decAttrs :: [FunAttr]+ , decComdat :: Maybe String } deriving (Data, Eq, Generic, Ord, Show, Typeable) -- | The function type of this declaration@@ -448,17 +719,18 @@ -- Function Definitions -------------------------------------------------------- data Define = Define- { defLinkage :: Maybe Linkage- , defRetType :: Type- , defName :: Symbol- , defArgs :: [Typed Ident]- , defVarArgs :: Bool- , defAttrs :: [FunAttr]- , defSection :: Maybe String- , defGC :: Maybe GC- , defBody :: [BasicBlock]- , defMetadata :: FnMdAttachments- , defComdat :: Maybe String+ { defLinkage :: Maybe Linkage+ , defVisibility :: Maybe Visibility+ , defRetType :: Type+ , defName :: Symbol+ , defArgs :: [Typed Ident]+ , defVarArgs :: Bool+ , defAttrs :: [FunAttr]+ , defSection :: Maybe String+ , defGC :: Maybe GC+ , defBody :: [BasicBlock]+ , defMetadata :: FnMdAttachments+ , defComdat :: Maybe String } deriving (Data, Eq, Generic, Ord, Show, Typeable) defFunType :: Define -> Type@@ -652,6 +924,11 @@ isFArith :: ArithOp -> Bool isFArith = not . isIArith +data UnaryArithOp+ = FNeg+ -- ^ Floating point negation.+ deriving (Data, Eq, Generic, Ord, Show, Typeable)+ -- | Binary bitwise operators. data BitOp = Shl Bool Bool@@ -744,6 +1021,11 @@ * Middle of basic block. * The result is the same as parameters. -} + | UnaryArith UnaryArithOp (Typed (Value' lab))+ {- ^ * Unary arithmetic operation.+ * Middle of basic block.+ * The result is the same as the parameter. -}+ | Bit BitOp (Typed (Value' lab)) (Value' lab) {- ^ * Binary bit-vector operation, both operands have the same type. * Middle of basic block.@@ -760,6 +1042,17 @@ * Middle of basic block. * The result is as indicated by the provided type. -} + | CallBr Type (Value' lab) [Typed (Value' lab)] lab [lab]+ {- ^ * Call a function in asm-goto style:+ return type;+ function operand;+ arguments;+ default basic block destination;+ other basic block destinations.+ * Middle of basic block.+ * The result is as indicated by the provided type.+ * Introduced in LLVM 9. -}+ | Alloca Type (Maybe (Typed (Value' lab))) (Maybe Int) {- ^ * Allocated space on the stack: type of elements;@@ -768,8 +1061,9 @@ * Middle of basic block. * Returns a pointer to hold the given number of elements. -} - | Load (Typed (Value' lab)) (Maybe AtomicOrdering) (Maybe Align)+ | Load Type (Typed (Value' lab)) (Maybe AtomicOrdering) (Maybe Align) {- ^ * Read a value from the given address:+ type being loaded; address to read from; atomic ordering; assumptions about alignment of the given pointer.@@ -834,10 +1128,11 @@ * Middle of basic block. * Returns a value of the specified type. -} - | GEP Bool (Typed (Value' lab)) [Typed (Value' lab)]+ | GEP Bool Type (Typed (Value' lab)) [Typed (Value' lab)] {- ^ * "Get element pointer", compute the address of a field in a structure: inbounds check (value poisoned if this fails);+ type to use as a basis for calculations; pointer to parent structure; path to a sub-component of a structure. * Middle of basic block.@@ -918,6 +1213,10 @@ | Resume (Typed (Value' lab)) + | Freeze (Typed (Value' lab))+ {- ^ * Used to stop propagation of @undef@ and @poison@ values.+ * Middle of basic block. -}+ deriving (Data, Eq, Functor, Generic, Ord, Show, Typeable) type Instr = Instr' BlockLabel@@ -935,6 +1234,7 @@ Ret{} -> True RetVoid -> True Jump{} -> True+ CallBr{} -> True Br{} -> True Unreachable -> True Unwind -> True@@ -985,6 +1285,7 @@ | ValZeroInit | ValAsm Bool Bool String String | ValMd (ValMd' lab)+ | ValPoison deriving (Data, Eq, Functor, Generic, Generic1, Ord, Show, Typeable) type Value = Value' BlockLabel@@ -1065,14 +1366,18 @@ -- Constant Expressions -------------------------------------------------------- data ConstExpr' lab- = ConstGEP Bool (Maybe Word64) (Maybe Type) [Typed (Value' lab)]- -- ^ Element type introduced in LLVM 3.7+ = ConstGEP Bool (Maybe Word64) Type (Typed (Value' lab)) [Typed (Value' lab)]+ -- ^ Since LLVM 3.7, constant @getelementptr@ expressions include an explicit+ -- type to use as a basis for calculations. For older versions of LLVM, this+ -- type can be reconstructed by inspecting the pointee type of the parent+ -- pointer value. | ConstConv ConvOp (Typed (Value' lab)) Type | ConstSelect (Typed (Value' lab)) (Typed (Value' lab)) (Typed (Value' lab))- | ConstBlockAddr Symbol lab+ | ConstBlockAddr (Typed (Value' lab)) lab | ConstFCmp FCmpOp (Typed (Value' lab)) (Typed (Value' lab)) | ConstICmp ICmpOp (Typed (Value' lab)) (Typed (Value' lab)) | ConstArith ArithOp (Typed (Value' lab)) (Value' lab)+ | ConstUnaryArith UnaryArithOp (Typed (Value' lab)) | ConstBit BitOp (Typed (Value' lab)) (Value' lab) deriving (Data, Eq, Functor, Generic, Generic1, Ord, Show, Typeable) @@ -1085,7 +1390,8 @@ | DebugInfoCompileUnit (DICompileUnit' lab) | DebugInfoCompositeType (DICompositeType' lab) | DebugInfoDerivedType (DIDerivedType' lab)- | DebugInfoEnumerator String !Int64+ | DebugInfoEnumerator String !Integer Bool+ -- ^ The 'Bool' field represents @isUnsigned@, introduced in LLVM 7. | DebugInfoExpression DIExpression | DebugInfoFile DIFile | DebugInfoGlobalVariable (DIGlobalVariable' lab)@@ -1094,13 +1400,16 @@ | DebugInfoLexicalBlockFile (DILexicalBlockFile' lab) | DebugInfoLocalVariable (DILocalVariable' lab) | DebugInfoSubprogram (DISubprogram' lab)- | DebugInfoSubrange DISubrange+ | DebugInfoSubrange (DISubrange' lab) | DebugInfoSubroutineType (DISubroutineType' lab) | DebugInfoNameSpace (DINameSpace' lab) | DebugInfoTemplateTypeParameter (DITemplateTypeParameter' lab) | DebugInfoTemplateValueParameter (DITemplateValueParameter' lab) | DebugInfoImportedEntity (DIImportedEntity' lab) | DebugInfoLabel (DILabel' lab)+ | DebugInfoArgList (DIArgList' lab)+ | DebugInfoAssignID+ -- ^ Introduced in LLVM 17. deriving (Data, Eq, Functor, Generic, Generic1, Ord, Show, Typeable) type DebugInfo = DebugInfo' BlockLabel@@ -1125,16 +1434,18 @@ type DITemplateTypeParameter = DITemplateTypeParameter' BlockLabel data DITemplateTypeParameter' lab = DITemplateTypeParameter- { dittpName :: Maybe String- , dittpType :: Maybe (ValMd' lab)+ { dittpName :: Maybe String+ , dittpType :: Maybe (ValMd' lab)+ , dittpIsDefault :: Maybe Bool -- since LLVM 11 } deriving (Data, Eq, Functor, Generic, Generic1, Ord, Show, Typeable) type DITemplateValueParameter = DITemplateValueParameter' BlockLabel data DITemplateValueParameter' lab = DITemplateValueParameter- { ditvpTag :: DwarfTag- , ditvpName :: Maybe String- , ditvpType :: Maybe (ValMd' lab)- , ditvpValue :: ValMd' lab+ { ditvpTag :: DwarfTag+ , ditvpName :: Maybe String+ , ditvpType :: Maybe (ValMd' lab)+ , ditvpIsDefault :: Maybe Bool -- since LLVM 11+ , ditvpValue :: ValMd' lab } deriving (Data, Eq, Functor, Generic, Generic1, Ord, Show, Typeable) type DINameSpace = DINameSpace' BlockLabel@@ -1184,6 +1495,12 @@ , dicuMacros :: Maybe (ValMd' lab) , dicuDWOId :: Word64 , dicuSplitDebugInlining :: Bool+ , dicuDebugInfoForProf :: Bool+ , dicuNameTableKind :: Word64+ -- added in LLVM 11: dicuRangesBaseAddress, dicuSysRoot, and dicuSDK+ , dicuRangesBaseAddress :: Bool+ , dicuSysRoot :: Maybe String+ , dicuSDK :: Maybe String } deriving (Data, Eq, Functor, Generic, Generic1, Ord, Show, Typeable) type DICompileUnit = DICompileUnit' BlockLabel@@ -1205,6 +1522,12 @@ , dictTemplateParams :: Maybe (ValMd' lab) , dictIdentifier :: Maybe String , dictDiscriminator :: Maybe (ValMd' lab)+ , dictDataLocation :: Maybe (ValMd' lab)+ , dictAssociated :: Maybe (ValMd' lab)+ , dictAllocated :: Maybe (ValMd' lab)+ , dictRank :: Maybe (ValMd' lab)+ , dictAnnotations :: Maybe (ValMd' lab)+ -- ^ Introduced in LLVM 14. } deriving (Data, Eq, Functor, Generic, Generic1, Ord, Show, Typeable) type DICompositeType = DICompositeType' BlockLabel@@ -1221,6 +1544,13 @@ , didtOffset :: Word64 , didtFlags :: DIFlags , didtExtraData :: Maybe (ValMd' lab)+ , didtDwarfAddressSpace :: Maybe Word32+ -- ^ Introduced in LLVM 5.+ --+ -- The 'Maybe' encodes the possibility that there is no associated address+ -- space (in LLVM, the sentinel value @0@ is used for this).+ , didtAnnotations :: Maybe (ValMd' lab)+ -- ^ Introduced in LLVM 14 } deriving (Data, Eq, Functor, Generic, Generic1, Ord, Show, Typeable) type DIDerivedType = DIDerivedType' BlockLabel@@ -1246,6 +1576,8 @@ , digvVariable :: Maybe (ValMd' lab) , digvDeclaration :: Maybe (ValMd' lab) , digvAlignment :: Maybe Word32+ , digvAnnotations :: Maybe (ValMd' lab)+ -- ^ Introduced in LLVM 14. } deriving (Data, Eq, Functor, Generic, Generic1, Ord, Show, Typeable) type DIGlobalVariable = DIGlobalVariable' BlockLabel@@ -1282,6 +1614,10 @@ , dilvType :: Maybe (ValMd' lab) , dilvArg :: Word16 , dilvFlags :: DIFlags+ , dilvAlignment :: Maybe Word32+ -- ^ Introduced in LLVM 4.+ , dilvAnnotations :: Maybe (ValMd' lab)+ -- ^ Introduced in LLVM 14. } deriving (Data, Eq, Functor, Generic, Generic1, Ord, Show, Typeable) type DILocalVariable = DILocalVariable' BlockLabel@@ -1305,17 +1641,46 @@ , dispUnit :: Maybe (ValMd' lab) , dispTemplateParams :: Maybe (ValMd' lab) , dispDeclaration :: Maybe (ValMd' lab)- , dispVariables :: Maybe (ValMd' lab)+ , dispRetainedNodes :: Maybe (ValMd' lab) , dispThrownTypes :: Maybe (ValMd' lab)+ , dispAnnotations :: Maybe (ValMd' lab)+ -- ^ Introduced in LLVM 14. } deriving (Data, Eq, Functor, Generic, Generic1, Ord, Show, Typeable) type DISubprogram = DISubprogram' BlockLabel -data DISubrange = DISubrange- { disrCount :: Int64- , disrLowerBound :: Int64- } deriving (Data, Eq, Generic, Ord, Show, Typeable)+-- | The DISubrange is a Value subrange specification, usually associated with+-- arrays or enumerations.+--+-- * Early LLVM: only 'disrCount' and 'disrLowerBound' were present, where both+-- were a direct signed 64-bit value. This corresponds to "format 0" in the+-- bitcode encoding (see reference below).+--+-- * LLVM 7: 'disrCount' changed to metadata representation ('ValMd'). The+-- metadata representation should only be a signed 64-bit integer, a Variable,+-- or an Expression. This corresponds to "format 1" in the bitcode encoding.+--+-- * LLVM 11: 'disrLowerBound' was changed to a metadata representation and+-- 'disrUpperBound' and 'disrStride' were added (primarily driven by the+-- addition of Fortran support in llvm). All three should only be represented+-- as a signed 64-bit integer, a Variable, or an Expression. This corresponds+-- to "format 2" in the bitcode encoding. See+-- https://github.com/llvm/llvm-project/commit/d20bf5a for this change.+--+-- Also see+-- https://github.com/llvm/llvm-project/blob/bbe8cd1/llvm/lib/Bitcode/Reader/MetadataLoader.cpp#L1435-L1461+-- for how this is read from the bitcode encoding and the use of the format+-- values mentioned above. +data DISubrange' lab = DISubrange+ { disrCount :: Maybe (ValMd' lab)+ , disrLowerBound :: Maybe (ValMd' lab)+ , disrUpperBound :: Maybe (ValMd' lab)+ , disrStride :: Maybe (ValMd' lab)+ } deriving (Data, Eq, Functor, Generic, Generic1, Ord, Show, Typeable)++type DISubrange = DISubrange' BlockLabel+ data DISubroutineType' lab = DISubroutineType { distFlags :: DIFlags , distTypeArray :: Maybe (ValMd' lab)@@ -1323,6 +1688,13 @@ type DISubroutineType = DISubroutineType' BlockLabel +-- | See <https://releases.llvm.org/13.0.0/docs/LangRef.html#diarglist>.+newtype DIArgList' lab = DIArgList+ { dialArgs :: [ValMd' lab]+ } deriving (Data, Eq, Functor, Generic, Generic1, Ord, Show, Typeable)++type DIArgList = DIArgList' BlockLabel+ -- Aggregate Utilities --------------------------------------------------------- data IndexResult@@ -1341,10 +1713,11 @@ -- on unknown type aliases will return 'Nothing' resolveGepFull :: (Ident -> Maybe Type) {- ^ Type alias resolution -} ->- Type {- ^ Pointer type -} ->+ Type {- ^ Base type used for calculations -} ->+ Typed (Value' lab) {- ^ Pointer value -} -> [Typed (Value' lab)] {- ^ Path -} -> Maybe Type {- ^ Type of result -}-resolveGepFull env t ixs = go (resolveGep t ixs)+resolveGepFull env baseTy tv ixs = go (resolveGep baseTy tv ixs) where go Invalid = Nothing go (HasType result) = Just result@@ -1353,16 +1726,32 @@ -- | Resolve the type of a GEP instruction. Note that the type produced is the -- type of the result, not necessarily a pointer.-resolveGep :: Type -> [Typed (Value' lab)] -> IndexResult-resolveGep (PtrTo ty0) (v:ixs0)- | isGepIndex v =- resolveGepBody ty0 ixs0-resolveGep ty0@PtrTo{} (v:ixs0)- | Just i <- elimAlias (typedType v) =- Resolve i (\ty' -> resolveGep ty0 (Typed ty' (typedValue v):ixs0))-resolveGep (Alias i) ixs =- Resolve i (\ty' -> resolveGep ty' ixs)-resolveGep _ _ = Invalid+resolveGep :: Type -> Typed (Value' lab) -> [Typed (Value' lab)] -> IndexResult+resolveGep baseTy tv ixs =+ case ixs of+ v:ixs0+ | -- If headed by a pointer and the first index value has a valid GEP+ -- index type, proceed to resolve the body of the GEP instruction.+ isPointer t+ , isGepIndex v+ -> resolveGepBody baseTy ixs0++ | -- If headed by a pointer and the first index has an alias type,+ -- resolve the alias and try again.+ isPointer t+ , Just i <- elimAlias (typedType v)+ -> Resolve i (\ty' -> resolveGep baseTy tv (Typed ty' (typedValue v):ixs0))++ _ | -- If headed by a value with an alias type, resolve the alias and+ -- try again.+ Alias i <- t+ -> Resolve i (\ty' -> resolveGep baseTy (Typed ty' (typedValue tv)) ixs)++ | -- Otherwise, the GEP instruction is invalid.+ otherwise+ -> Invalid+ where+ t = typedType tv -- | Resolve the type of a GEP instruction. This assumes that the input has -- already been processed as a pointer.
src/Text/LLVM/DebugUtils.hs view
@@ -1,16 +1,17 @@ {-# Language TransformListComp, MonadComprehensions #-} {- |-Module : $Header$+Module : Text.LLVM.DebugUtils Description : This module interprets the DWARF information associated with a function's argument and return types in order to interpret field name references. License : BSD3 Stability : provisional-Point-of-contact : emertens+Maintainer : emertens@galois.com -} module Text.LLVM.DebugUtils ( -- * Definition type analyzer- Info(..), computeFunctionTypes, valMdToInfo+ Info(..), StructFieldInfo(..), BitfieldInfo(..), UnionFieldInfo(..)+ , computeFunctionTypes, valMdToInfo , localVariableNameDeclarations -- * Metadata lookup@@ -23,10 +24,19 @@ -- * Info hueristics , guessAliasInfo+ , guessTypeInfo++ -- * Function arguments+ , debugInfoArgNames++ -- * Line numbers of definitions+ , debugInfoGlobalLines+ , debugInfoDefineLines ) where import Control.Applicative ((<|>)) import Control.Monad ((<=<))+import Data.Bits (Bits(..)) import Data.IntMap (IntMap) import qualified Data.IntMap as IntMap import Data.List (elemIndex, tails, stripPrefix)@@ -56,27 +66,99 @@ data Info = Pointer Info- | Structure [(String,Word64,Info)] -- ^ Fields: name, bit-offset, info- | Union [(String,Info)]+ | Structure (Maybe String) [StructFieldInfo]+ | Union (Maybe String) [UnionFieldInfo]+ | Typedef String Info | ArrInfo Info- | BaseType String+ | BaseType String DIBasicType | Unknown deriving Show -{--import Text.Show.Pretty-import Data.Foldable+-- | Record debug information about a field in a struct type.+data StructFieldInfo = StructFieldInfo+ { sfiName :: String+ -- ^ The field name.+ , sfiOffset :: Word64+ -- ^ The field's offset (in bits) from the start of the struct.+ , sfiBitfield :: Maybe BitfieldInfo+ -- ^ If this field resides within a bitfield, this is+ -- @'Just' bitfieldInfo@. Otherwise, this is 'Nothing'.+ , sfiInfo :: Info+ -- ^ The debug 'Info' associated with the field's type.+ } deriving Show -test =- do test' "/Users/emertens/Source/saw/saw-script\- \/examples/llvm/dotprod_struct.bc"- test' "/Users/emertens/Desktop/temp.bc"+-- | Record debug information about a field within a bitfield. For example,+-- the following C struct:+--+-- @+-- struct s {+-- int32_t w;+-- uint8_t x1:1;+-- uint8_t x2:2;+-- uint8_t y:1;+-- int32_t z;+-- };+-- @+--+-- Corresponds to the following 'Info':+--+-- @+-- 'Structure'+-- [ 'StructFieldInfo' { 'sfiName' = \"w\"+-- , 'sfiOffset' = 0+-- , 'sfiBitfield' = Nothing+-- , 'sfiInfo' = 'BaseType' \"int32_t\"+-- }+-- , 'StructFieldInfo' { 'sfiName' = \"x1\"+-- , 'sfiOffset' = 32+-- , 'sfiBitfield' = Just ('BitfieldInfo' { 'biFieldSize' = 1+-- , 'biBitfieldOffset' = 32+-- })+-- , 'sfiInfo' = 'BaseType' \"uint8_t\"+-- }+-- , 'StructFieldInfo' { 'sfiName' = \"x2\"+-- , 'sfiOffset' = 33+-- , 'sfiBitfield' = Just ('BitfieldInfo' { 'biFieldSize' = 2+-- , 'biBitfieldOffset' = 32+-- })+-- , 'sfiInfo' = BaseType \"uint8_t\"+-- }+-- , 'StructFieldInfo' { 'sfiName' = \"y\"+-- , 'sfiOffset' = 35+-- , 'sfiBitfield' = Just ('BitfieldInfo' { 'biFieldSize' = 1+-- , 'biBitfieldOffset' = 32+-- })+-- , 'sfiInfo' = 'BaseType' \"uint8_t\"+-- }+-- , 'StructFieldInfo' { 'sfiName' = \"z\"+-- , 'sfiOffset' = 64+-- , 'sfiBitfield' = Nothing+-- , 'sfiInfo' = BaseType \"int32_t\"+-- }+-- ]+-- @+--+-- Notice that only @x1@, @x2@, and @y@ have 'BitfieldInfo's, as they are the+-- only fields that were declared with bitfield syntax.+data BitfieldInfo = BitfieldInfo+ { biFieldSize :: Word64+ -- ^ The field's size (in bits) within the bitfield. This should not be+ -- confused with the size of the field's declared type. For example, the+ -- 'biFieldSize' of the @x1@ field is @1@, despite the fact that its+ -- declared type, @uint8_t@, is otherwise 8 bits in size.+ , biBitfieldOffset :: Word64+ -- ^ The bitfield's offset (in bits) from the start of the struct. Note+ -- that for a given field within a bitfield, its 'sfiOffset' is equal to+ -- the 'biBitfieldOffset' plus the 'biFieldSize'.+ } deriving Show -test' fn =- do Right bc <- parseBitCodeFromFile fn- let mdMap = mkMdMap bc- traverse_ (putStrLn . ppShow . analyzeDefine mdMap) (modDefines bc)--}+-- | Record debug information about a field in a union type.+data UnionFieldInfo = UnionFieldInfo+ { ufiName :: String+ -- ^ The field name.+ , ufiInfo :: Info+ -- ^ The debug 'Info' associated with the field's type.+ } deriving Show -- | Compute an 'IntMap' of the unnamed metadata in a module mkMdMap :: Module -> IntMap ValMd@@ -89,6 +171,10 @@ getDebugInfo _ (ValMdDebugInfo di) = Just di getDebugInfo _ _ = Nothing +getInteger :: MdMap -> ValMd -> Maybe Integer+getInteger mdMap (ValMdRef i) = getInteger mdMap =<< IntMap.lookup i mdMap+getInteger _ (ValMdValue (Typed _ (ValInteger i))) = Just i+getInteger _ _ = Nothing getList :: MdMap -> ValMd -> Maybe [Maybe ValMd] getList mdMap (ValMdRef i) = getList mdMap =<< IntMap.lookup i mdMap@@ -109,13 +195,15 @@ debugInfoToInfo :: MdMap -> DebugInfo -> Info debugInfoToInfo mdMap (DebugInfoDerivedType dt) | didtTag dt == dwarfPointer = Pointer (valMdToInfo' mdMap (didtBaseType dt))- | didtTag dt == dwarfTypedef = valMdToInfo' mdMap (didtBaseType dt)- | didtTag dt == dwarfConst = valMdToInfo' mdMap (didtBaseType dt)+ | didtTag dt == dwarfTypedef = case didtName dt of+ Nothing -> valMdToInfo' mdMap (didtBaseType dt)+ Just nm -> Typedef nm (valMdToInfo' mdMap (didtBaseType dt))+ | didtTag dt == dwarfConst = valMdToInfo' mdMap (didtBaseType dt) debugInfoToInfo _ (DebugInfoBasicType bt)- | dibtTag bt == dwarfBasetype = BaseType (dibtName bt)+ | dibtTag bt == dwarfBasetype = BaseType (dibtName bt) bt debugInfoToInfo mdMap (DebugInfoCompositeType ct)- | dictTag ct == dwarfStruct = maybe Unknown Structure (getStructFields mdMap ct)- | dictTag ct == dwarfUnion = maybe Unknown Union (getUnionFields mdMap ct)+ | dictTag ct == dwarfStruct = maybe Unknown (Structure (dictName ct)) (getStructFields mdMap ct)+ | dictTag ct == dwarfUnion = maybe Unknown (Union (dictName ct)) (getUnionFields mdMap ct) | dictTag ct == dwarfArray = ArrInfo (valMdToInfo' mdMap (dictBaseType ct)) debugInfoToInfo _ _ = Unknown @@ -124,26 +212,47 @@ getFieldDIs mdMap = traverse (getDebugInfo mdMap) <=< sequence <=< getList mdMap <=< dictElements --getStructFields :: MdMap -> DICompositeType -> Maybe [(String, Word64, Info)]+getStructFields :: MdMap -> DICompositeType -> Maybe [StructFieldInfo] getStructFields mdMap = traverse (debugInfoToStructField mdMap) <=< getFieldDIs mdMap -debugInfoToStructField :: MdMap -> DebugInfo -> Maybe (String, Word64, Info)+debugInfoToStructField :: MdMap -> DebugInfo -> Maybe StructFieldInfo debugInfoToStructField mdMap di = do DebugInfoDerivedType dt <- Just di fieldName <- didtName dt- Just (fieldName, didtOffset dt, valMdToInfo' mdMap (didtBaseType dt))+ -- We check if a struct field resides within a bitfield by checking its+ -- `flags` field sets `BitField`, which has a numeric value of 19.+ -- (https://github.com/llvm/llvm-project/blob/1bebc31c617d1a0773f1d561f02dd17c5e83b23b/llvm/include/llvm/IR/DebugInfoFlags.def#L51)+ --+ -- If so, the `size` field records the size in bits, and the `extraData`+ -- field records the offset of the overall bitfield from the start of the+ -- struct.+ -- (https://github.com/llvm/llvm-project/blob/ee7652569854af567ba83e5255d70e80cc8619a1/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp#L2489-L2508)+ let bitfield | testBit (didtFlags dt) 19+ , Just extraData <- didtExtraData dt+ , Just bitfieldOffset <- getInteger mdMap extraData+ = Just $ BitfieldInfo { biFieldSize = didtSize dt+ , biBitfieldOffset = fromInteger bitfieldOffset+ }+ | otherwise+ = Nothing+ Just (StructFieldInfo { sfiName = fieldName+ , sfiOffset = didtOffset dt+ , sfiBitfield = bitfield+ , sfiInfo = valMdToInfo' mdMap (didtBaseType dt)+ }) -getUnionFields :: MdMap -> DICompositeType -> Maybe [(String, Info)]+getUnionFields :: MdMap -> DICompositeType -> Maybe [UnionFieldInfo] getUnionFields mdMap = traverse (debugInfoToUnionField mdMap) <=< getFieldDIs mdMap -debugInfoToUnionField :: MdMap -> DebugInfo -> Maybe (String, Info)+debugInfoToUnionField :: MdMap -> DebugInfo -> Maybe UnionFieldInfo debugInfoToUnionField mdMap di = do DebugInfoDerivedType dt <- Just di fieldName <- didtName dt- Just (fieldName, valMdToInfo' mdMap (didtBaseType dt))+ Just (UnionFieldInfo { ufiName = fieldName+ , ufiInfo = valMdToInfo' mdMap (didtBaseType dt)+ }) @@ -154,9 +263,9 @@ computeFunctionTypes :: Module {- ^ module to search -} -> Symbol {- ^ function symbol -} ->- Maybe [Info] {- ^ return and argument type information -}+ Maybe [Maybe Info] {- ^ return and argument type information -} computeFunctionTypes m sym =- [ maybe (BaseType "void") (valMdToInfo mdMap) <$> types+ [ fmap (valMdToInfo mdMap) <$> types | let mdMap = mkMdMap m , sp <- findSubprogramViaDefine mdMap m sym <|> findSubprogramViaCu mdMap m sym@@ -219,9 +328,10 @@ Info {- ^ type information for specified field -} fieldIndexByPosition i info = case info of- Structure xs -> go [ x | (_,_,x) <- xs ]- Union xs -> go [ x | (_,x) <- xs ]- _ -> Unknown+ Typedef _ info' -> fieldIndexByPosition i info'+ Structure _ xs -> go [ x | StructFieldInfo{sfiInfo = x} <- xs ]+ Union _ xs -> go [ x | UnionFieldInfo{ufiInfo = x} <- xs ]+ _ -> Unknown where go xs = case drop i xs of [] -> Unknown@@ -235,9 +345,10 @@ Maybe Int {- ^ zero-based index of field matching the name -} fieldIndexByName n info = case info of- Structure xs -> go [ x | (x,_,_) <- xs ]- Union xs -> go [ x | (x,_) <- xs ]- _ -> Nothing+ Typedef _ info' -> fieldIndexByName n info'+ Structure _ xs -> go [ x | StructFieldInfo{sfiName = x} <- xs ]+ Union _ xs -> go [ x | UnionFieldInfo{ufiName = x} <- xs ]+ _ -> Nothing where go = elemIndex n @@ -291,21 +402,29 @@ -- because there's no direct mapping between type aliases -- and debug info. The debug information must be search -- for a textual match.+--+-- Compared to @guessTypeInfo@, this function first tries+-- to strip the \"struct.\" and \"union.\" prefixes that are+-- commonly added by clang before searching for the type information. guessAliasInfo :: IntMap ValMd {- ^ unnamed metadata -} -> Ident {- ^ alias -} -> Info-guessAliasInfo mdMap (Ident name) =- -- TODO: Support more categories than struct- case stripPrefix "struct." name of- Nothing -> Unknown- Just pfx -> guessStructInfo mdMap pfx+guessAliasInfo mdMap (Ident name)+ | Just pfx <- stripPrefix "struct." name = guessTypeInfo mdMap pfx+ | Just pfx <- stripPrefix "union." name = guessTypeInfo mdMap pfx+ | otherwise = guessTypeInfo mdMap name -guessStructInfo ::+-- | Search the metadata for debug info corresponding+-- to a given type alias. This is considered a heuristic+-- because there's no direct mapping between type aliases+-- and debug info. The debug information must be search+-- for a textual match.+guessTypeInfo :: IntMap ValMd {- ^ unnamed metadata -} -> String {- ^ struct alias -} -> Info-guessStructInfo mdMap name =+guessTypeInfo mdMap name = case mapMaybe (go <=< getDebugInfo mdMap) (IntMap.elems mdMap) of [] -> Unknown x:_ -> x@@ -319,4 +438,67 @@ , Just name == dictName dict = Just (debugInfoToInfo mdMap di) + go _ = Nothing++------------------------------------------------------------------------++-- | Find source-level names of function arguments+debugInfoArgNames :: Module -> Define -> IntMap String+debugInfoArgNames m d =+ case Map.lookup dbgKind $ defMetadata d of+ Just (ValMdRef s) -> scopeArgs s+ _ -> IntMap.empty+ where+ scopeArgs :: Int -> IntMap String+ scopeArgs s = IntMap.fromList . mapMaybe go $ modUnnamedMd m+ where+ go :: UnnamedMd -> Maybe (Int, String)+ go+ ( UnnamedMd+ { umValues =+ ValMdDebugInfo+ ( DebugInfoLocalVariable+ DILocalVariable+ { dilvScope = Just (ValMdRef s'),+ dilvArg = a,+ dilvName = Just n+ }+ )+ }) =+ if s == s'+ then Just (fromIntegral a - 1, n)+ else Nothing+ go _ = Nothing++------------------------------------------------------------------------++-- | Map global variable names to the line on which the global is defined+debugInfoGlobalLines :: Module -> Map String Int+debugInfoGlobalLines = Map.fromList . mapMaybe go . modUnnamedMd+ where+ go :: UnnamedMd -> Maybe (String, Int)+ go (UnnamedMd+ { umValues = ValMdDebugInfo+ (DebugInfoGlobalVariable DIGlobalVariable+ { digvName = Just n+ , digvLine = l+ }+ )+ }) = Just (n, (fromIntegral l))+ go _ = Nothing++-- | Map function names to the line on which the function is defined+debugInfoDefineLines :: Module -> Map String Int+debugInfoDefineLines = Map.fromList . mapMaybe go . modUnnamedMd+ where+ go :: UnnamedMd -> Maybe (String, Int)+ go (UnnamedMd+ { umValues = ValMdDebugInfo+ (DebugInfoSubprogram DISubprogram+ { dispName = Just n+ , dispIsDefinition = True+ , dispLine = l+ }+ )+ }) = Just (n, (fromIntegral l)) go _ = Nothing
src/Text/LLVM/Labels.hs view
@@ -1,21 +1,10 @@-{-# LANGUAGE CPP #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE EmptyCase, TypeOperators, FlexibleContexts #-}--#ifndef MIN_VERSION_base-#define MIN_VERSION_base(x,y,z) 1-#endif- module Text.LLVM.Labels where import Text.LLVM.AST import Text.LLVM.Labels.TH -#if !(MIN_VERSION_base(4,8,0))-import Control.Applicative ((<$>),Applicative(..))-import Data.Traversable (traverse)-#endif- class Functor f => HasLabel f where -- | Given a function for resolving labels, where the presence of a symbol -- denotes a label in a different function, rename all labels in a function.@@ -30,6 +19,8 @@ relabel f (Arith op l r) = Arith op <$> traverse (relabel f) l <*> relabel f r+ relabel f (UnaryArith op a) = UnaryArith op+ <$> traverse (relabel f) a relabel f (Bit op l r) = Bit op <$> traverse (relabel f) l <*> relabel f r@@ -37,10 +28,18 @@ relabel f (Call t r n as) = Call t r <$> relabel f n <*> traverse (traverse (relabel f)) as+ relabel f (CallBr r n as u es) = CallBr r+ <$> relabel f n+ <*> traverse (traverse (relabel f)) as+ <*> f Nothing u+ <*> traverse (f Nothing) es relabel f (Alloca t n a) = Alloca t <$> traverse (traverse (relabel f)) n <*> pure a- relabel f (Load a mo ma) = Load <$> traverse (relabel f) a <*> pure mo <*> pure ma+ relabel f (Load t a mo ma) = Load t+ <$> traverse (relabel f) a+ <*> pure mo+ <*> pure ma relabel f (Store d v mo ma) = Store <$> traverse (relabel f) d <*> traverse (relabel f) v@@ -67,7 +66,7 @@ relabel f (FCmp op l r) = FCmp op <$> traverse (relabel f) l <*> relabel f r- relabel f (GEP ib a is) = GEP ib+ relabel f (GEP ib t a is) = GEP ib t <$> traverse (relabel f) a <*> traverse (traverse (relabel f)) is relabel f (Select c l r) = Select@@ -120,6 +119,7 @@ <*> traverse (relabel f) cs relabel f (Resume tv) = Resume <$> traverse (relabel f) tv+ relabel f (Freeze tv) = Freeze <$> traverse (relabel f) tv instance HasLabel Stmt' where relabel = $(generateRelabel 'relabel ''Stmt') instance HasLabel Clause' where relabel = $(generateRelabel 'relabel ''Clause')@@ -130,6 +130,7 @@ instance HasLabel DebugInfo' where relabel = $(generateRelabel 'relabel ''DebugInfo') instance HasLabel DIDerivedType' where relabel = $(generateRelabel 'relabel ''DIDerivedType') instance HasLabel DISubroutineType' where relabel = $(generateRelabel 'relabel ''DISubroutineType')+instance HasLabel DISubrange' where relabel = $(generateRelabel 'relabel ''DISubrange') instance HasLabel DIGlobalVariable' where relabel = $(generateRelabel 'relabel ''DIGlobalVariable') instance HasLabel DIGlobalVariableExpression' where relabel = $(generateRelabel 'relabel ''DIGlobalVariableExpression') instance HasLabel DILocalVariable' where relabel = $(generateRelabel 'relabel ''DILocalVariable')@@ -142,8 +143,10 @@ instance HasLabel DITemplateTypeParameter' where relabel = $(generateRelabel 'relabel ''DITemplateTypeParameter') instance HasLabel DITemplateValueParameter' where relabel = $(generateRelabel 'relabel ''DITemplateValueParameter') instance HasLabel DIImportedEntity' where relabel = $(generateRelabel 'relabel ''DIImportedEntity')+instance HasLabel DIArgList' where relabel = $(generateRelabel 'relabel ''DIArgList') -- | Clever instance that actually uses the block name instance HasLabel ConstExpr' where- relabel f (ConstBlockAddr t l) = ConstBlockAddr t <$> f (Just t) l+ relabel f (ConstBlockAddr t@(Typed { typedValue = ValSymbol s }) l) =+ ConstBlockAddr <$> traverse (relabel f) t <*> f (Just s) l relabel f x = $(generateRelabel 'relabel ''ConstExpr') f x
src/Text/LLVM/Lens.hs view
@@ -30,7 +30,7 @@ , ''DebugLoc' , ''DebugInfo' , ''DIFile- , ''DISubrange+ , ''DISubrange' , ''DIBasicType , ''DIExpression , ''DISubprogram'@@ -43,6 +43,7 @@ , ''DIDerivedType' , ''DILexicalBlock' , ''DILexicalBlockFile'+ , ''DIArgList' , ''Instr' , ''ValMd' , ''ConvOp
src/Text/LLVM/PP.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE ImplicitParams #-}+{-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE Rank2Types #-} @@ -17,9 +18,11 @@ module Text.LLVM.PP where import Text.LLVM.AST+import Text.LLVM.Triple.AST (TargetTriple)+import Text.LLVM.Triple.Print (printTriple) import Control.Applicative ((<|>))-import Data.Bits ( shiftR )+import Data.Bits ( shiftR, (.&.) ) import Data.Char (isAlphaNum,isAscii,isDigit,isPrint,ord,toUpper) import Data.List (intersperse) import qualified Data.Map as Map@@ -32,53 +35,96 @@ -- Pretty-printer Config ------------------------------------------------------- -type LLVM = ?config :: Config --- | The differences between various versions of the llvm textual AST.-data Config = Config { cfgLoadImplicitType :: Bool- -- ^ True when the type of the result of a load is- -- derived from its pointer argument, or supplied- -- implicitly.+-- | The value used to specify the LLVM major version. The LLVM text format+-- (i.e. assembly code) changes with different versions of LLVM, so this value is+-- used to select the version the output should be generated for.+--+-- At the current time, changes primarily occur when the LLVM major version+-- changes, and this is expected to be the case going forward, so it is+-- sufficient to reference the LLVM version by the single major version number.+-- There is one exception and one possible future exception to this approach:+--+-- 1. During LLVM v3, there were changes in 3.5, 3.6, 3.7, and 3.8. There are+-- explicit @ppLLVMnn@ function entry points for those versions, but in the+-- event that a numerical value is needed, we note the serendipitous fact+-- that prior to LLVM 4, there are exactly 4 versions we need to+-- differentiate and can therefore assign the values of 0, 1, 2, and 3 to+-- those versions (and we have no intention of supporting any other pre-4.0+-- versions at this point).+--+-- 2. If at some future date, there are text format changes associated with a+-- minor version, then the LLVM version designation here will need to be+-- enhanced and made more sophisticated. At the present time, the likelihood+-- of that is small enough that the current simple implementation is a+-- benefit over a more complex mechanism that might not be needed.+--+type LLVMVer = Int - , cfgGEPImplicitType :: Bool- -- ^ True when the type of the result of the GEP- -- instruction is implied.+-- | Helpers for specifying the LLVM versions prior to v4+llvmV3_5, llvmV3_6, llvmV3_7, llvmV3_8 :: LLVMVer+llvmV3_5 = 0+llvmV3_6 = 1+llvmV3_7 = 2+llvmV3_8 = 3 - , cfgUseDILocation :: Bool- }+-- | This value should be updated when support is added for new LLVM versions;+-- this is used for defaulting and otherwise reporting the maximum LLVM version+-- known to be supported.+llvmVlatest :: LLVMVer+llvmVlatest = 17 -withConfig :: Config -> (LLVM => a) -> a++-- | The differences between various versions of the llvm textual AST.+newtype Config = Config { cfgVer :: LLVMVer }++withConfig :: Config -> ((?config :: Config) => a) -> a withConfig cfg body = let ?config = cfg in body -ppLLVM, ppLLVM35, ppLLVM36, ppLLVM37, ppLLVM38 :: (LLVM => a) -> a+ppLLVM :: LLVMVer -> ((?config :: Config) => a) -> a+ppLLVM llvmver = withConfig Config { cfgVer = llvmver } -ppLLVM = ppLLVM38+ppLLVM35, ppLLVM36, ppLLVM37, ppLLVM38 :: ((?config :: Config) => a) -> a -ppLLVM35 = ppLLVM36+ppLLVM35 = withConfig Config { cfgVer = llvmV3_5 }+ppLLVM36 = withConfig Config { cfgVer = llvmV3_6 }+ppLLVM37 = withConfig Config { cfgVer = llvmV3_7 }+ppLLVM38 = withConfig Config { cfgVer = llvmV3_8 } -ppLLVM36 = withConfig Config { cfgLoadImplicitType = True- , cfgGEPImplicitType = True- , cfgUseDILocation = False- }-ppLLVM37 = withConfig Config { cfgLoadImplicitType = False- , cfgGEPImplicitType = False- , cfgUseDILocation = True- }-ppLLVM38 = withConfig Config { cfgLoadImplicitType = False- , cfgGEPImplicitType = False- , cfgUseDILocation = True- }+llvmVer :: (?config :: Config) => LLVMVer+llvmVer = cfgVer ?config -checkConfig :: LLVM => (Config -> Bool) -> Bool-checkConfig p = p ?config+-- | This is a helper function for when a list of parameters is gated by a+-- condition (usually the llvmVer value).+when' :: Monoid a => Bool -> a -> a+when' c l = if c then l else mempty +-- | This type encapsulates the ability to convert an object into Doc+-- format. Using this abstraction allows for a consolidated representation of the+-- declaration. Most pretty-printing for LLVM elements will have a @'Fmt' a@+-- function signature for that element.+type Fmt a = (?config :: Config) => a -> Doc+++-- | The LLVMPretty class has instances for most AST elements. It allows the+-- conversion of an AST element (and its sub-elements) into a Doc assembly format+-- by simply using the 'llvmPP' method rather than needing to explicitly invoke+-- the specific pretty-printing function for that element.+class LLVMPretty a where llvmPP :: Fmt a++instance LLVMPretty Module where llvmPP = ppModule+instance LLVMPretty Symbol where llvmPP = ppSymbol+instance LLVMPretty Ident where llvmPP = ppIdent++ -- Modules --------------------------------------------------------------------- -ppModule :: LLVM => Module -> Doc+ppModule :: Fmt Module ppModule m = foldr ($+$) empty $ ppSourceName (modSourceName m)+ : ppTargetTriple (modTriple m) : ppDataLayout (modDataLayout m) : ppInlineAsm (modInlineAsm m) : concat [ map ppTypeDecl (modTypes m)@@ -94,18 +140,18 @@ -- Source filename ------------------------------------------------------------- -ppSourceName :: Maybe String -> Doc+ppSourceName :: Fmt (Maybe String) ppSourceName Nothing = empty ppSourceName (Just sn) = "source_filename" <+> char '=' <+> doubleQuotes (text sn) -- Metadata -------------------------------------------------------------------- -ppNamedMd :: NamedMd -> Doc+ppNamedMd :: Fmt NamedMd ppNamedMd nm = sep [ ppMetadata (text (nmName nm)) <+> char '=' , ppMetadata (braces (commas (map (ppMetadata . int) (nmValues nm)))) ] -ppUnnamedMd :: LLVM => UnnamedMd -> Doc+ppUnnamedMd :: Fmt UnnamedMd ppUnnamedMd um = sep [ ppMetadata (int (umIndex um)) <+> char '=' , distinct <+> ppValMd (umValues um) ]@@ -116,8 +162,12 @@ -- Aliases --------------------------------------------------------------------- -ppGlobalAlias :: LLVM => GlobalAlias -> Doc-ppGlobalAlias g = ppSymbol (aliasName g) <+> char '=' <+> body+ppGlobalAlias :: Fmt GlobalAlias+ppGlobalAlias g = ppSymbol (aliasName g)+ <+> char '='+ <+> ppMaybe ppLinkage (aliasLinkage g)+ <+> ppMaybe ppVisibility (aliasVisibility g)+ <+> body where val = aliasTarget g body = case val of@@ -125,16 +175,23 @@ _ -> ppValue val +-- Target triple ---------------------------------------------------------------++-- | Pretty print a 'TargetTriple'+ppTargetTriple :: Fmt TargetTriple+ppTargetTriple triple = "target" <+> "triple" <+> char '='+ <+> doubleQuotes (text (printTriple triple))+ -- Data Layout ----------------------------------------------------------------- -- | Pretty print a data layout specification.-ppDataLayout :: DataLayout -> Doc+ppDataLayout :: Fmt DataLayout ppDataLayout [] = empty ppDataLayout ls = "target" <+> "datalayout" <+> char '=' <+> doubleQuotes (hcat (intersperse (char '-') (map ppLayoutSpec ls))) -- | Pretty print a single layout specification.-ppLayoutSpec :: LayoutSpec -> Doc+ppLayoutSpec :: Fmt LayoutSpec ppLayoutSpec ls = case ls of BigEndian -> char 'E'@@ -153,14 +210,14 @@ Mangling m -> char 'm' <> char ':' <> ppMangling m -- | Pretty-print the common case for data layout specifications.-ppLayoutBody :: Int -> Int -> Maybe Int -> Doc+ppLayoutBody :: Int -> Int -> Fmt (Maybe Int) ppLayoutBody size abi mb = int size <> char ':' <> int abi <> pref where pref = case mb of Nothing -> empty Just p -> char ':' <> int p -ppMangling :: Mangling -> Doc+ppMangling :: Fmt Mangling ppMangling ElfMangling = char 'e' ppMangling MipsMangling = char 'm' ppMangling MachOMangling = char 'o'@@ -170,7 +227,7 @@ -- Inline Assembly ------------------------------------------------------------- -- | Pretty-print the inline assembly block.-ppInlineAsm :: InlineAsm -> Doc+ppInlineAsm :: Fmt InlineAsm ppInlineAsm = foldr ($+$) empty . map ppLine where ppLine l = "module asm" <+> doubleQuotes (text l)@@ -178,7 +235,7 @@ -- Identifiers ----------------------------------------------------------------- -ppIdent :: Ident -> Doc+ppIdent :: Fmt Ident ppIdent (Ident n) | validIdentifier n = char '%' <> text n | otherwise = char '%' <> ppStringLiteral n@@ -198,7 +255,7 @@ -- Symbols --------------------------------------------------------------------- -ppSymbol :: Symbol -> Doc+ppSymbol :: Fmt Symbol ppSymbol (Symbol n) | validIdentifier n = char '@' <> text n | otherwise = char '@' <> ppStringLiteral n@@ -206,7 +263,7 @@ -- Types ----------------------------------------------------------------------- -ppPrimType :: PrimType -> Doc+ppPrimType :: Fmt PrimType ppPrimType Label = "label" ppPrimType Void = "void" ppPrimType (Integer i) = char 'i' <> integer (toInteger i)@@ -214,7 +271,7 @@ ppPrimType X86mmx = "x86mmx" ppPrimType Metadata = "metadata" -ppFloatType :: FloatType -> Doc+ppFloatType :: Fmt FloatType ppFloatType Half = "half" ppFloatType Float = "float" ppFloatType Double = "double"@@ -222,73 +279,79 @@ ppFloatType X86_fp80 = "x86_fp80" ppFloatType PPC_fp128 = "ppc_fp128" -ppType :: Type -> Doc+ppType :: Fmt Type ppType (PrimType pt) = ppPrimType pt ppType (Alias i) = ppIdent i ppType (Array len ty) = brackets (integral len <+> char 'x' <+> ppType ty) ppType (PtrTo ty) = ppType ty <> char '*'+ppType PtrOpaque = "ptr" ppType (Struct ts) = structBraces (commas (map ppType ts)) ppType (PackedStruct ts) = angles (structBraces (commas (map ppType ts))) ppType (FunTy r as va) = ppType r <> ppArgList va (map ppType as) ppType (Vector len pt) = angles (integral len <+> char 'x' <+> ppType pt) ppType Opaque = "opaque" -ppTypeDecl :: TypeDecl -> Doc+ppTypeDecl :: Fmt TypeDecl ppTypeDecl td = ppIdent (typeName td) <+> char '=' <+> "type" <+> ppType (typeValue td) -- Declarations ---------------------------------------------------------------- -ppGlobal :: LLVM => Global -> Doc+ppGlobal :: Fmt Global ppGlobal g = ppSymbol (globalSym g) <+> char '='- <+> ppTheGlobalAttrs (globalAttrs g)+ <+> ppGlobalAttrs (isJust $ globalValue g) (globalAttrs g) <+> ppType (globalType g) <+> ppMaybe ppValue (globalValue g) <> ppAlign (globalAlign g) <> ppAttachedMetadata (Map.toList (globalMetadata g))- where- isStruct | Just (ValStruct {}) <- globalValue g = True- | otherwise = False- ppTheGlobalAttrs | isStruct = ppStructGlobalAttrs- | otherwise = ppGlobalAttrs -ppGlobalAttrs :: GlobalAttrs -> Doc-ppGlobalAttrs ga+-- | Pretty-print Global Attributes (usually associated with a global variable+-- declaration). The first argument to ppGlobalAttrs indicates whether there is a+-- value associated with this global declaration: a global declaration with a+-- value should not be identified as \"external\" and \"default\" visibility,+-- whereas one without a value may have those attributes.++ppGlobalAttrs :: Bool -> Fmt GlobalAttrs+ppGlobalAttrs hasValue ga -- LLVM 3.8 does not emit or parse linkage information w/ hidden visibility | Just HiddenVisibility <- gaVisibility ga = ppVisibility HiddenVisibility <+> constant- | otherwise = ppMaybe ppLinkage (gaLinkage ga) <+> ppMaybe ppVisibility (gaVisibility ga) <+> constant- where- constant | gaConstant ga = "constant"- | otherwise = "global"--ppStructGlobalAttrs :: GlobalAttrs -> Doc-ppStructGlobalAttrs ga- -- LLVM 3.8 does not emit or parse external linkage for- -- global structs- | Just External <- gaLinkage ga,- Just DefaultVisibility <- gaVisibility ga- = constant- | otherwise = ppGlobalAttrs ga+ | Just External <- gaLinkage ga+ , Just DefaultVisibility <- gaVisibility ga+ , hasValue =+ -- Just show the value, no "external" or "default". This is based on+ -- empirical testing as described in the comment above (testing the+ -- following 6 configurations:+ -- * uninitialized scalar+ -- * uninitialized structure+ -- * initialized scalar+ -- * initialized structure+ -- * external scalar+ -- * external structure+ constant+ | otherwise =+ ppMaybe ppLinkage (gaLinkage ga) <+> ppMaybe ppVisibility (gaVisibility ga) <+> constant where constant | gaConstant ga = "constant" | otherwise = "global" -ppDeclare :: Declare -> Doc+ppDeclare :: Fmt Declare ppDeclare d = "declare"+ <+> ppMaybe ppLinkage (decLinkage d)+ <+> ppMaybe ppVisibility (decVisibility d) <+> ppType (decRetType d) <+> ppSymbol (decName d) <> ppArgList (decVarArgs d) (map ppType (decArgs d)) <+> hsep (ppFunAttr <$> decAttrs d) <> maybe empty ((char ' ' <>) . ppComdatName) (decComdat d) -ppComdatName :: String -> Doc+ppComdatName :: Fmt String ppComdatName s = "comdat" <> parens (char '$' <> text s) -ppComdat :: (String,SelectionKind) -> Doc+ppComdat :: Fmt (String,SelectionKind) ppComdat (n,k) = ppComdatName n <+> char '=' <+> text "comdat" <+> ppSelectionKind k -ppSelectionKind :: SelectionKind -> Doc+ppSelectionKind :: Fmt SelectionKind ppSelectionKind k = case k of ComdatAny -> "any"@@ -297,9 +360,10 @@ ComdatNoDuplicates -> "noduplicates" ComdatSameSize -> "samesize" -ppDefine :: LLVM => Define -> Doc+ppDefine :: Fmt Define ppDefine d = "define" <+> ppMaybe ppLinkage (defLinkage d)+ <+> ppMaybe ppVisibility (defVisibility d) <+> ppType (defRetType d) <+> ppSymbol (defName d) <> ppArgList (defVarArgs d) (map (ppTyped ppIdent) (defArgs d))@@ -318,7 +382,7 @@ -- FunAttr --------------------------------------------------------------------- -ppFunAttr :: FunAttr -> Doc+ppFunAttr :: Fmt FunAttr ppFunAttr a = case a of AlignStack w -> text "alignstack" <> parens (int w)@@ -352,28 +416,28 @@ -- Basic Blocks ---------------------------------------------------------------- -ppLabelDef :: BlockLabel -> Doc+ppLabelDef :: Fmt BlockLabel ppLabelDef (Named (Ident l)) = text l <> char ':' ppLabelDef (Anon i) = char ';' <+> "<label>:" <+> int i -ppLabel :: BlockLabel -> Doc+ppLabel :: Fmt BlockLabel ppLabel (Named l) = ppIdent l ppLabel (Anon i) = char '%' <> int i -ppBasicBlock :: LLVM => BasicBlock -> Doc+ppBasicBlock :: Fmt BasicBlock ppBasicBlock bb = ppMaybe ppLabelDef (bbLabel bb) $+$ nest 2 (vcat (map ppStmt (bbStmts bb))) -- Statements ------------------------------------------------------------------ -ppStmt :: LLVM => Stmt -> Doc+ppStmt :: Fmt Stmt ppStmt stmt = case stmt of Result var i mds -> ppIdent var <+> char '=' <+> ppInstr i <> ppAttachedMetadata mds Effect i mds -> ppInstr i <> ppAttachedMetadata mds -ppAttachedMetadata :: LLVM => [(String,ValMd)] -> Doc+ppAttachedMetadata :: Fmt [(String,ValMd)] ppAttachedMetadata mds | null mds = empty | otherwise = comma <+> commas (map step mds)@@ -383,7 +447,7 @@ -- Linkage --------------------------------------------------------------------- -ppLinkage :: Linkage -> Doc+ppLinkage :: Fmt Linkage ppLinkage linkage = case linkage of Private -> "private" LinkerPrivate -> "linker_private"@@ -402,28 +466,28 @@ DLLImport -> "dllimport" DLLExport -> "dllexport" -ppVisibility :: Visibility -> Doc+ppVisibility :: Fmt Visibility ppVisibility v = case v of DefaultVisibility -> "default" HiddenVisibility -> "hidden" ProtectedVisibility -> "protected" -ppGC :: GC -> Doc+ppGC :: Fmt GC ppGC = doubleQuotes . text . getGC -- Expressions ----------------------------------------------------------------- -ppTyped :: (a -> Doc) -> Typed a -> Doc+ppTyped :: Fmt a -> Fmt (Typed a) ppTyped fmt ty = ppType (typedType ty) <+> fmt (typedValue ty) -ppSignBits :: Bool -> Bool -> Doc+ppSignBits :: Bool -> Fmt Bool ppSignBits nuw nsw = opt nuw "nuw" <+> opt nsw "nsw" -ppExact :: Bool -> Doc+ppExact :: Fmt Bool ppExact e = opt e "exact" -ppArithOp :: ArithOp -> Doc+ppArithOp :: Fmt ArithOp ppArithOp (Add nuw nsw) = "add" <+> ppSignBits nuw nsw ppArithOp FAdd = "fadd" ppArithOp (Sub nuw nsw) = "sub" <+> ppSignBits nuw nsw@@ -437,7 +501,10 @@ ppArithOp SRem = "srem" ppArithOp FRem = "frem" -ppBitOp :: BitOp -> Doc+ppUnaryArithOp :: Fmt UnaryArithOp+ppUnaryArithOp FNeg = "fneg"++ppBitOp :: Fmt BitOp ppBitOp (Shl nuw nsw) = "shl" <+> ppSignBits nuw nsw ppBitOp (Lshr e) = "lshr" <+> ppExact e ppBitOp (Ashr e) = "ashr" <+> ppExact e@@ -445,7 +512,7 @@ ppBitOp Or = "or" ppBitOp Xor = "xor" -ppConvOp :: ConvOp -> Doc+ppConvOp :: Fmt ConvOp ppConvOp Trunc = "trunc" ppConvOp ZExt = "zext" ppConvOp SExt = "sext"@@ -459,7 +526,7 @@ ppConvOp IntToPtr = "inttoptr" ppConvOp BitCast = "bitcast" -ppAtomicOrdering :: AtomicOrdering -> Doc+ppAtomicOrdering :: Fmt AtomicOrdering ppAtomicOrdering Unordered = text "unordered" ppAtomicOrdering Monotonic = text "monotonic" ppAtomicOrdering Acquire = text "acquire"@@ -467,7 +534,7 @@ ppAtomicOrdering AcqRel = text "acq_rel" ppAtomicOrdering SeqCst = text "seq_cst" -ppAtomicOp :: AtomicRWOp -> Doc+ppAtomicOp :: Fmt AtomicRWOp ppAtomicOp AtomicXchg = "xchg" ppAtomicOp AtomicAdd = "add" ppAtomicOp AtomicSub = "sub"@@ -480,23 +547,25 @@ ppAtomicOp AtomicUMax = "umax" ppAtomicOp AtomicUMin = "umin" -ppScope :: Maybe String -> Doc+ppScope :: Fmt (Maybe String) ppScope Nothing = empty ppScope (Just s) = "syncscope" <> parens (doubleQuotes (text s)) -ppInstr :: LLVM => Instr -> Doc+ppInstr :: Fmt Instr ppInstr instr = case instr of Ret tv -> "ret" <+> ppTyped ppValue tv RetVoid -> "ret void" Arith op l r -> ppArithOp op <+> ppTyped ppValue l <> comma <+> ppValue r+ UnaryArith op a -> ppUnaryArithOp op <+> ppTyped ppValue a Bit op l r -> ppBitOp op <+> ppTyped ppValue l <> comma <+> ppValue r Conv op a ty -> ppConvOp op <+> ppTyped ppValue a <+> "to" <+> ppType ty Call tc ty f args -> ppCall tc ty f args+ CallBr ty f args u es -> ppCallBr ty f args u es Alloca ty len align -> ppAlloca ty len align- Load ptr mo ma -> ppLoad ptr mo ma+ Load ty ptr mo ma -> ppLoad ty ptr mo ma Store a ptr mo ma -> ppStore a ptr mo ma Fence scope order -> "fence" <+> ppScope scope <+> ppAtomicOrdering order CmpXchg w v p a n s o o' -> "cmpxchg" <+> opt w "weak"@@ -531,7 +600,7 @@ ShuffleVector a b m -> "shufflevector" <+> ppTyped ppValue a <> comma <+> ppTyped ppValue (b <$ a) <> comma <+> ppTyped ppValue m- GEP ib ptr ixs -> ppGEP ib ptr ixs+ GEP ib ty ptr ixs -> ppGEP ib ty ptr ixs Comment str -> char ';' <+> text str Jump i -> "br" <+> ppTypedLabel i@@ -572,11 +641,12 @@ <+> ppType ty $$ nest 2 (ppClauses c cs) Resume tv -> "resume" <+> ppTyped ppValue tv+ Freeze tv -> "freeze" <+> ppTyped ppValue tv -ppLoad :: LLVM => Typed (Value' BlockLabel) -> Maybe AtomicOrdering -> Maybe Align -> Doc-ppLoad ptr mo ma =+ppLoad :: Type -> Typed (Value' BlockLabel) -> Maybe AtomicOrdering -> Fmt (Maybe Align)+ppLoad ty ptr mo ma = "load" <+> (if isAtomic then "atomic" else empty)- <+> (if isImplicit then empty else explicit)+ <+> (if isExplicit then explicit else empty) <+> ppTyped ppValue ptr <+> ordering <> ppAlign ma@@ -584,24 +654,19 @@ where isAtomic = isJust mo - isImplicit = checkConfig cfgLoadImplicitType+ isExplicit = llvmVer >= llvmV3_7 ordering = case mo of Just ao -> ppAtomicOrdering ao _ -> empty - explicit =- case typedType ptr of- PtrTo ty -> ppType ty <> comma- ty -> ppType ty <> comma+ explicit = ppType ty <> comma -ppStore :: LLVM- => Typed (Value' BlockLabel)+ppStore :: Typed (Value' BlockLabel) -> Typed (Value' BlockLabel) -> Maybe AtomicOrdering- -> Maybe Align- -> Doc+ -> Fmt (Maybe Align) ppStore ptr val mo ma = "store" <+> (if isJust mo then "atomic" else empty) <+> ppTyped ppValue ptr <> comma@@ -612,32 +677,32 @@ <> ppAlign ma -ppClauses :: LLVM => Bool -> [Clause] -> Doc+ppClauses :: Bool -> Fmt [Clause] ppClauses isCleanup cs = vcat (cleanup : map ppClause cs) where cleanup | isCleanup = "cleanup" | otherwise = empty -ppClause :: LLVM => Clause -> Doc+ppClause :: Fmt Clause ppClause c = case c of Catch tv -> "catch" <+> ppTyped ppValue tv Filter tv -> "filter" <+> ppTyped ppValue tv -ppTypedLabel :: BlockLabel -> Doc+ppTypedLabel :: Fmt BlockLabel ppTypedLabel i = ppType (PrimType Label) <+> ppLabel i -ppSwitchEntry :: Type -> (Integer,BlockLabel) -> Doc+ppSwitchEntry :: Type -> Fmt (Integer,BlockLabel) ppSwitchEntry ty (i,l) = ppType ty <+> integer i <> comma <+> ppTypedLabel l -ppVectorIndex :: LLVM => Value -> Doc+ppVectorIndex :: Fmt Value ppVectorIndex i = ppType (PrimType (Integer 32)) <+> ppValue i -ppAlign :: Maybe Align -> Doc+ppAlign :: Fmt (Maybe Align) ppAlign Nothing = empty ppAlign (Just align) = comma <+> "align" <+> int align -ppAlloca :: LLVM => Type -> Maybe (Typed Value) -> Maybe Int -> Doc+ppAlloca :: Type -> Maybe (Typed Value) -> Fmt (Maybe Int) ppAlloca ty mbLen mbAlign = "alloca" <+> ppType ty <> len <> align where len = fromMaybe empty $ do@@ -647,7 +712,7 @@ a <- mbAlign return (comma <+> "align" <+> int a) -ppCall :: LLVM => Bool -> Type -> Value -> [Typed Value] -> Doc+ppCall :: Bool -> Type -> Value -> Fmt [Typed Value] ppCall tc ty f args | tc = "tail" <+> body | otherwise = body@@ -655,37 +720,66 @@ body = "call" <+> ppCallSym ty f <> parens (commas (map (ppTyped ppValue) args)) -ppCallSym :: LLVM => Type -> Value -> Doc-ppCallSym (PtrTo (FunTy res args va)) val = ppType res <+> ppArgList va (map ppType args) <+> ppValue val-ppCallSym ty val = ppType ty <+> ppValue val+-- | Note that the textual syntax changed in LLVM 10 (@callbr@ was introduced in+-- LLVM 9).+ppCallBr :: Type -> Value -> [Typed Value] -> BlockLabel -> Fmt [BlockLabel]+ppCallBr ty f args to indirectDests =+ "callbr"+ <+> ppCallSym ty f <> parens (commas (map (ppTyped ppValue) args))+ <+> "to" <+> ppLab to <+> brackets (commas (map ppLab indirectDests))+ where+ ppLab l = ppType (PrimType Label) <+> ppLabel l -ppGEP :: LLVM => Bool -> Typed Value -> [Typed Value] -> Doc-ppGEP ib ptr ixs = "getelementptr" <+> inbounds- <+> (if isImplicit then empty else explicit)- <+> commas (map (ppTyped ppValue) (ptr:ixs))+-- | Print out the @<ty>|<fnty> <fnptrval>@ portion of a @call@, @callbr@, or+-- @invoke@ instruction, where:+--+-- * @<ty>@ is the return type.+--+-- * @<fnty>@ is the overall function type.+--+-- * @<fnptrval>@ is a pointer value, where the memory it points to is treated+-- as a value of type @<fnty>@.+--+-- The LLVM Language Reference Manual indicates that either @<ty>@ or @<fnty>@+-- can be used, but in practice, @<ty>@ is typically preferred unless the+-- function type involves varargs. We adopt the same convention here.+ppCallSym :: Type -> Fmt Value+ppCallSym ty val = pp_ty <+> ppValue val where- isImplicit = checkConfig cfgGEPImplicitType+ pp_ty =+ case ty of+ FunTy res args va+ | va+ -> ppType res <+> ppArgList va (map ppType args)+ | otherwise+ -> ppType res+ _ -> ppType ty - explicit =- case typedType ptr of- PtrTo ty -> ppType ty <> comma- ty -> ppType ty <> comma+ppGEP :: Bool -> Type -> Typed Value -> Fmt [Typed Value]+ppGEP ib ty ptr ixs =+ "getelementptr" <+> inbounds+ <+> (if isExplicit then explicit else empty)+ <+> commas (map (ppTyped ppValue) (ptr:ixs))+ where+ isExplicit = llvmVer >= llvmV3_7 + explicit = ppType ty <> comma+ inbounds | ib = "inbounds" | otherwise = empty -ppInvoke :: LLVM => Type -> Value -> [Typed Value] -> BlockLabel -> BlockLabel -> Doc+ppInvoke :: Type -> Value -> [Typed Value] -> BlockLabel -> Fmt BlockLabel ppInvoke ty f args to uw = body where- body = "invoke" <+> ppType ty <+> ppValue f+ body = "invoke" <+> ppCallSym ty f <> parens (commas (map (ppTyped ppValue) args)) <+> "to" <+> ppType (PrimType Label) <+> ppLabel to <+> "unwind" <+> ppType (PrimType Label) <+> ppLabel uw -ppPhiArg :: LLVM => (Value,BlockLabel) -> Doc+ppPhiArg :: Fmt (Value,BlockLabel) ppPhiArg (v,l) = char '[' <+> ppValue v <> comma <+> ppLabel l <+> char ']' -ppICmpOp :: ICmpOp -> Doc+ppICmpOp :: Fmt ICmpOp ppICmpOp Ieq = "eq" ppICmpOp Ine = "ne" ppICmpOp Iugt = "ugt"@@ -697,7 +791,7 @@ ppICmpOp Islt = "slt" ppICmpOp Isle = "sle" -ppFCmpOp :: FCmpOp -> Doc+ppFCmpOp :: Fmt FCmpOp ppFCmpOp Ffalse = "false" ppFCmpOp Foeq = "oeq" ppFCmpOp Fogt = "ogt"@@ -715,7 +809,7 @@ ppFCmpOp Funo = "uno" ppFCmpOp Ftrue = "true" -ppValue' :: LLVM => (i -> Doc) -> Value' i -> Doc+ppValue' :: Fmt i -> Fmt (Value' i) ppValue' pp val = case val of ValInteger i -> integer i ValBool b -> ppBool b@@ -726,7 +820,7 @@ -- https://llvm.org/docs/LangRef.html#simple-constants let pad n | n < 0x10 = shows (0::Int) . showHex n | otherwise = showHex n- fld v i = pad $ v `shiftR` (i * 8)+ fld v i = pad ((v `shiftR` (i * 8)) .&. 0xff) in "0xK" <> text (foldr (fld e) (foldr (fld s) "" $ reverse [0..7::Int]) [1, 0]) ValIdent i -> ppIdent i ValSymbol s -> ppSymbol s@@ -745,11 +839,12 @@ ValZeroInit -> "zeroinitializer" ValAsm s a i c -> ppAsm s a i c ValMd m -> ppValMd' pp m+ ValPoison -> "poison" -ppValue :: LLVM => Value -> Doc+ppValue :: Fmt Value ppValue = ppValue' ppLabel -ppValMd' :: LLVM => (i -> Doc) -> ValMd' i -> Doc+ppValMd' :: Fmt i -> Fmt (ValMd' i) ppValMd' pp m = case m of ValMdString str -> ppMetadata (ppStringLiteral str) ValMdValue tv -> ppTyped (ppValue' pp) tv@@ -758,12 +853,12 @@ ValMdLoc l -> ppDebugLoc' pp l ValMdDebugInfo di -> ppDebugInfo' pp di -ppValMd :: LLVM => ValMd -> Doc+ppValMd :: Fmt ValMd ppValMd = ppValMd' ppLabel -ppDebugLoc' :: LLVM => (i -> Doc) -> DebugLoc' i -> Doc-ppDebugLoc' pp dl = (if cfgUseDILocation ?config then "!DILocation"- else "!MDLocation")+ppDebugLoc' :: Fmt i -> Fmt (DebugLoc' i)+ppDebugLoc' pp dl = (if llvmVer >= llvmV3_7 then "!DILocation"+ else "!MDLocation") <> parens (commas [ "line:" <+> integral (dlLine dl) , "column:" <+> integral (dlCol dl) , "scope:" <+> ppValMd' pp (dlScope dl)@@ -775,23 +870,23 @@ Nothing -> empty mbImplicit = if dlImplicit dl then comma <+> "implicit" else empty -ppDebugLoc :: LLVM => DebugLoc -> Doc+ppDebugLoc :: Fmt DebugLoc ppDebugLoc = ppDebugLoc' ppLabel -ppTypedValMd :: LLVM => ValMd -> Doc+ppTypedValMd :: Fmt ValMd ppTypedValMd = ppTyped ppValMd . Typed (PrimType Metadata) -ppMetadata :: Doc -> Doc+ppMetadata :: Fmt Doc ppMetadata body = char '!' <> body -ppMetadataNode' :: LLVM => (i -> Doc) -> [Maybe (ValMd' i)] -> Doc+ppMetadataNode' :: Fmt i -> Fmt [Maybe (ValMd' i)] ppMetadataNode' pp vs = ppMetadata (braces (commas (map arg vs))) where arg = maybe ("null") (ppValMd' pp) -ppMetadataNode :: LLVM => [Maybe ValMd] -> Doc+ppMetadataNode :: Fmt [Maybe ValMd] ppMetadataNode = ppMetadataNode' ppLabel -ppStringLiteral :: String -> Doc+ppStringLiteral :: Fmt String ppStringLiteral = doubleQuotes . text . concatMap escape where escape c | c == '"' || c == '\\' = '\\' : showHex (fromEnum c) ""@@ -801,7 +896,7 @@ pad n | n < 0x10 = '0' : map toUpper (showHex n "") | otherwise = map toUpper (showHex n "") -ppAsm :: Bool -> Bool -> String -> String -> Doc+ppAsm :: Bool -> Bool -> String -> Fmt String ppAsm s a i c = "asm" <+> sideeffect <+> alignstack <+> ppStringLiteral i <> comma <+> ppStringLiteral c@@ -813,38 +908,39 @@ | otherwise = empty -ppConstExpr' :: LLVM => (i -> Doc) -> ConstExpr' i -> Doc+ppConstExpr' :: Fmt i -> Fmt (ConstExpr' i) ppConstExpr' pp expr = case expr of- ConstGEP inb _mix mp ixs ->+ ConstGEP inb _mix ty ptr ixs -> "getelementptr" <+> opt inb "inbounds"- <+> parens (mcommas ((ppType <$> mp) : (map (pure . ppTyp') ixs)))+ <+> parens (commas (ppType ty : map ppTyp' (ptr:ixs))) ConstConv op tv t -> ppConvOp op <+> parens (ppTyp' tv <+> "to" <+> ppType t) ConstSelect c l r -> "select" <+> parens (commas [ ppTyp' c, ppTyp' l , ppTyp' r])- ConstBlockAddr t l -> "blockaddress" <+> parens (ppSymbol t <> comma <+> pp l)- ConstFCmp op a b -> "fcmp" <+> ppFCmpOp op <+> ppTupleT a b- ConstICmp op a b -> "icmp" <+> ppICmpOp op <+> ppTupleT a b- ConstArith op a b -> ppArithOp op <+> ppTuple a b- ConstBit op a b -> ppBitOp op <+> ppTuple a b+ ConstBlockAddr t l -> "blockaddress" <+> parens (ppVal' (typedValue t) <> comma <+> pp l)+ ConstFCmp op a b -> "fcmp" <+> ppFCmpOp op <+> ppTupleT a b+ ConstICmp op a b -> "icmp" <+> ppICmpOp op <+> ppTupleT a b+ ConstArith op a b -> ppArithOp op <+> ppTuple a b+ ConstUnaryArith op a -> ppUnaryArithOp op <+> ppTyp' a+ ConstBit op a b -> ppBitOp op <+> ppTuple a b where ppTuple a b = parens $ ppTyped ppVal' a <> comma <+> ppVal' b ppTupleT a b = parens $ ppTyped ppVal' a <> comma <+> ppTyp' b ppVal' = ppValue' pp ppTyp' = ppTyped ppVal' -ppConstExpr :: LLVM => ConstExpr -> Doc+ppConstExpr :: Fmt ConstExpr ppConstExpr = ppConstExpr' ppLabel -- DWARF Debug Info ------------------------------------------------------------ -ppDebugInfo' :: LLVM => (i -> Doc) -> DebugInfo' i -> Doc+ppDebugInfo' :: Fmt i -> Fmt (DebugInfo' i) ppDebugInfo' pp di = case di of DebugInfoBasicType bt -> ppDIBasicType bt DebugInfoCompileUnit cu -> ppDICompileUnit' pp cu DebugInfoCompositeType ct -> ppDICompositeType' pp ct DebugInfoDerivedType dt -> ppDIDerivedType' pp dt- DebugInfoEnumerator nm v -> ppDIEnumerator nm v+ DebugInfoEnumerator nm v u -> ppDIEnumerator nm v u DebugInfoExpression e -> ppDIExpression e DebugInfoFile f -> ppDIFile f DebugInfoGlobalVariable gv -> ppDIGlobalVariable' pp gv@@ -853,18 +949,20 @@ DebugInfoLexicalBlockFile lbf -> ppDILexicalBlockFile' pp lbf DebugInfoLocalVariable lv -> ppDILocalVariable' pp lv DebugInfoSubprogram sp -> ppDISubprogram' pp sp- DebugInfoSubrange sr -> ppDISubrange sr+ DebugInfoSubrange sr -> ppDISubrange' pp sr DebugInfoSubroutineType st -> ppDISubroutineType' pp st DebugInfoNameSpace ns -> ppDINameSpace' pp ns DebugInfoTemplateTypeParameter dttp -> ppDITemplateTypeParameter' pp dttp DebugInfoTemplateValueParameter dtvp -> ppDITemplateValueParameter' pp dtvp DebugInfoImportedEntity diip -> ppDIImportedEntity' pp diip DebugInfoLabel dil -> ppDILabel' pp dil+ DebugInfoArgList args -> ppDIArgList' pp args+ DebugInfoAssignID -> "!DIAssignID()" -ppDebugInfo :: LLVM => DebugInfo -> Doc+ppDebugInfo :: Fmt DebugInfo ppDebugInfo = ppDebugInfo' ppLabel -ppDIImportedEntity' :: LLVM => (i -> Doc) -> DIImportedEntity' i -> Doc+ppDIImportedEntity' :: Fmt i -> Fmt (DIImportedEntity' i) ppDIImportedEntity' pp ie = "!DIImportedEntity" <> parens (mcommas [ pure ("tag:" <+> integral (diieTag ie)) , (("scope:" <+>) . ppValMd' pp) <$> diieScope ie@@ -874,21 +972,21 @@ , (("name:" <+>) . text) <$> diieName ie ]) -ppDIImportedEntity :: LLVM => DIImportedEntity -> Doc+ppDIImportedEntity :: Fmt DIImportedEntity ppDIImportedEntity = ppDIImportedEntity' ppLabel -ppDILabel' :: LLVM => (i -> Doc) -> DILabel' i -> Doc+ppDILabel' :: Fmt i -> Fmt (DILabel' i) ppDILabel' pp ie = "!DILabel" <> parens (mcommas [ (("scope:" <+>) . ppValMd' pp) <$> dilScope ie- , pure ("name:" <+> text (dilName ie))+ , pure ("name:" <+> ppStringLiteral (dilName ie)) , (("file:" <+>) . ppValMd' pp) <$> dilFile ie , pure ("line:" <+> integral (dilLine ie)) ]) -ppDILabel :: LLVM => DILabel -> Doc+ppDILabel :: Fmt DILabel ppDILabel = ppDILabel' ppLabel -ppDINameSpace' :: LLVM => (i -> Doc) -> DINameSpace' i -> Doc+ppDINameSpace' :: Fmt i -> Fmt (DINameSpace' i) ppDINameSpace' pp ns = "!DINameSpace" <> parens (mcommas [ ("name:" <+>) . text <$> (dinsName ns) , pure ("scope:" <+> ppValMd' pp (dinsScope ns))@@ -896,19 +994,19 @@ , pure ("line:" <+> integral (dinsLine ns)) ]) -ppDINameSpace :: LLVM => DINameSpace -> Doc+ppDINameSpace :: Fmt DINameSpace ppDINameSpace = ppDINameSpace' ppLabel -ppDITemplateTypeParameter' :: LLVM => (i -> Doc) -> DITemplateTypeParameter' i -> Doc+ppDITemplateTypeParameter' :: Fmt i -> Fmt (DITemplateTypeParameter' i) ppDITemplateTypeParameter' pp tp = "!DITemplateTypeParameter" <> parens (mcommas [ ("name:" <+>) . text <$> dittpName tp , ("type:" <+>) . ppValMd' pp <$> dittpType tp ]) -ppDITemplateTypeParameter :: LLVM => DITemplateTypeParameter -> Doc+ppDITemplateTypeParameter :: Fmt DITemplateTypeParameter ppDITemplateTypeParameter = ppDITemplateTypeParameter' ppLabel -ppDITemplateValueParameter' :: LLVM => (i -> Doc) -> DITemplateValueParameter' i -> Doc+ppDITemplateValueParameter' :: Fmt i -> Fmt (DITemplateValueParameter' i) ppDITemplateValueParameter' pp vp = "!DITemplateValueParameter" <> parens (mcommas [ pure ("tag:" <+> integral (ditvpTag vp)) , ("name:" <+>) . text <$> ditvpName vp@@ -916,10 +1014,10 @@ , pure ("value:" <+> ppValMd' pp (ditvpValue vp)) ]) -ppDITemplateValueParameter :: LLVM => DITemplateValueParameter -> Doc+ppDITemplateValueParameter :: Fmt DITemplateValueParameter ppDITemplateValueParameter = ppDITemplateValueParameter' ppLabel -ppDIBasicType :: DIBasicType -> Doc+ppDIBasicType :: Fmt DIBasicType ppDIBasicType bt = "!DIBasicType" <> parens (commas [ "tag:" <+> integral (dibtTag bt) , "name:" <+> doubleQuotes (text (dibtName bt))@@ -932,35 +1030,48 @@ Just flags -> comma <+> "flags:" <+> integral flags Nothing -> empty -ppDICompileUnit' :: LLVM => (i -> Doc) -> DICompileUnit' i -> Doc+ppDICompileUnit' :: Fmt i -> Fmt (DICompileUnit' i) ppDICompileUnit' pp cu = "!DICompileUnit"- <> parens (mcommas- [ pure ("language:" <+> integral (dicuLanguage cu))- , (("file:" <+>) . ppValMd' pp) <$> (dicuFile cu)- , (("producer:" <+>) . doubleQuotes . text)+ <> parens (mcommas $+ [ pure ("language:" <+> integral (dicuLanguage cu))+ , (("file:" <+>) . ppValMd' pp) <$> (dicuFile cu)+ , (("producer:" <+>) . doubleQuotes . text) <$> (dicuProducer cu)- , pure ("isOptimized:" <+> ppBool (dicuIsOptimized cu))- , pure ("flags:" <+> ppFlags (dicuFlags cu))- , pure ("runtimeVersion:" <+> integral (dicuRuntimeVersion cu))- , (("splitDebugFilename:" <+>) . doubleQuotes . text)+ , pure ("isOptimized:" <+> ppBool (dicuIsOptimized cu))+ , pure ("flags:" <+> ppFlags (dicuFlags cu))+ , pure ("runtimeVersion:" <+> integral (dicuRuntimeVersion cu))+ , (("splitDebugFilename:" <+>) . doubleQuotes . text) <$> (dicuSplitDebugFilename cu)- , pure ("emissionKind:" <+> integral (dicuEmissionKind cu))- , (("enums:" <+>) . ppValMd' pp) <$> (dicuEnums cu)- , (("retainedTypes:" <+>) . ppValMd' pp) <$> (dicuRetainedTypes cu)- , (("subprograms:" <+>) . ppValMd' pp) <$> (dicuSubprograms cu)- , (("globals:" <+>) . ppValMd' pp) <$> (dicuGlobals cu)- , (("imports:" <+>) . ppValMd' pp) <$> (dicuImports cu)- , (("macros:" <+>) . ppValMd' pp) <$> (dicuMacros cu)- , pure ("dwoId:" <+> integral (dicuDWOId cu))- ])+ , pure ("emissionKind:" <+> integral (dicuEmissionKind cu))+ , (("enums:" <+>) . ppValMd' pp) <$> (dicuEnums cu)+ , (("retainedTypes:" <+>) . ppValMd' pp) <$> (dicuRetainedTypes cu)+ , (("subprograms:" <+>) . ppValMd' pp) <$> (dicuSubprograms cu)+ , (("globals:" <+>) . ppValMd' pp) <$> (dicuGlobals cu)+ , (("imports:" <+>) . ppValMd' pp) <$> (dicuImports cu)+ , (("macros:" <+>) . ppValMd' pp) <$> (dicuMacros cu)+ , pure ("dwoId:" <+> integral (dicuDWOId cu))+ , pure ("splitDebugInlining:" <+> ppBool (dicuSplitDebugInlining cu))+ , pure ("debugInfoForProfiling:" <+> ppBool (dicuDebugInfoForProf cu))+ , pure ("nameTableKind:" <+> integral (dicuNameTableKind cu))+ ]+ +++ when' (llvmVer >= 11)+ [ pure ("rangesBaseAddress:" <+> ppBool (dicuRangesBaseAddress cu))+ , (("sysroot:" <+>) . doubleQuotes . text)+ <$> (dicuSysRoot cu)+ , (("sdk:" <+>) . doubleQuotes . text)+ <$> (dicuSDK cu)+ ]+ ) -ppDICompileUnit :: LLVM => DICompileUnit -> Doc++ppDICompileUnit :: Fmt DICompileUnit ppDICompileUnit = ppDICompileUnit' ppLabel -ppFlags :: Maybe String -> Doc+ppFlags :: Fmt (Maybe String) ppFlags mb = doubleQuotes (maybe empty text mb) -ppDICompositeType' :: LLVM => (i -> Doc) -> DICompositeType' i -> Doc+ppDICompositeType' :: Fmt i -> Fmt (DICompositeType' i) ppDICompositeType' pp ct = "!DICompositeType" <> parens (mcommas [ pure ("tag:" <+> integral (dictTag ct))@@ -979,46 +1090,54 @@ , (("identifier:" <+>) . doubleQuotes . text) <$> (dictIdentifier ct) , (("discriminator:" <+>) . ppValMd' pp) <$> (dictDiscriminator ct)+ , (("associated:" <+>) . ppValMd' pp) <$> (dictAssociated ct)+ , (("allocated:" <+>) . ppValMd' pp) <$> (dictAllocated ct)+ , (("rank:" <+>) . ppValMd' pp) <$> (dictRank ct)+ , (("annotations:" <+>) . ppValMd' pp) <$> (dictAnnotations ct) ]) -ppDICompositeType :: LLVM => DICompositeType -> Doc+ppDICompositeType :: Fmt DICompositeType ppDICompositeType = ppDICompositeType' ppLabel -ppDIDerivedType' :: LLVM => (i -> Doc) -> DIDerivedType' i -> Doc+ppDIDerivedType' :: Fmt i -> Fmt (DIDerivedType' i) ppDIDerivedType' pp dt = "!DIDerivedType" <> parens (mcommas [ pure ("tag:" <+> integral (didtTag dt)) , (("name:" <+>) . doubleQuotes . text) <$> (didtName dt) , (("file:" <+>) . ppValMd' pp) <$> (didtFile dt) , pure ("line:" <+> integral (didtLine dt))+ , (("scope:" <+>) . ppValMd' pp) <$> (didtScope dt) , ("baseType:" <+>) <$> (ppValMd' pp <$> didtBaseType dt <|> Just "null") , pure ("size:" <+> integral (didtSize dt)) , pure ("align:" <+> integral (didtAlign dt)) , pure ("offset:" <+> integral (didtOffset dt)) , pure ("flags:" <+> integral (didtFlags dt)) , (("extraData:" <+>) . ppValMd' pp) <$> (didtExtraData dt)+ , (("dwarfAddressSpace:" <+>) . integral) <$> didtDwarfAddressSpace dt+ , (("annotations:" <+>) . ppValMd' pp) <$> (didtAnnotations dt) ]) -ppDIDerivedType :: LLVM => DIDerivedType -> Doc+ppDIDerivedType :: Fmt DIDerivedType ppDIDerivedType = ppDIDerivedType' ppLabel -ppDIEnumerator :: String -> Int64 -> Doc-ppDIEnumerator n v = "!DIEnumerator"+ppDIEnumerator :: String -> Integer -> Fmt Bool+ppDIEnumerator n v u = "!DIEnumerator" <> parens (commas [ "name:" <+> doubleQuotes (text n) , "value:" <+> integral v+ , "isUnsigned:" <+> ppBool u ]) -ppDIExpression :: DIExpression -> Doc+ppDIExpression :: Fmt DIExpression ppDIExpression e = "!DIExpression" <> parens (commas (map integral (dieElements e))) -ppDIFile :: DIFile -> Doc+ppDIFile :: Fmt DIFile ppDIFile f = "!DIFile" <> parens (commas [ "filename:" <+> doubleQuotes (text (difFilename f)) , "directory:" <+> doubleQuotes (text (difDirectory f)) ]) -ppDIGlobalVariable' :: LLVM => (i -> Doc) -> DIGlobalVariable' i -> Doc+ppDIGlobalVariable' :: Fmt i -> Fmt (DIGlobalVariable' i) ppDIGlobalVariable' pp gv = "!DIGlobalVariable" <> parens (mcommas [ (("scope:" <+>) . ppValMd' pp) <$> (digvScope gv)@@ -1033,22 +1152,23 @@ , (("variable:" <+>) . ppValMd' pp) <$> (digvVariable gv) , (("declaration:" <+>) . ppValMd' pp) <$> (digvDeclaration gv) , (("align:" <+>) . integral) <$> digvAlignment gv+ , (("annotations:" <+>) . ppValMd' pp) <$> (digvAnnotations gv) ]) -ppDIGlobalVariable :: LLVM => DIGlobalVariable -> Doc+ppDIGlobalVariable :: Fmt DIGlobalVariable ppDIGlobalVariable = ppDIGlobalVariable' ppLabel -ppDIGlobalVariableExpression' :: LLVM => (i -> Doc) -> DIGlobalVariableExpression' i -> Doc+ppDIGlobalVariableExpression' :: Fmt i -> Fmt (DIGlobalVariableExpression' i) ppDIGlobalVariableExpression' pp gve = "!DIGlobalVariableExpression" <> parens (mcommas [ (("var:" <+>) . ppValMd' pp) <$> (digveVariable gve) , (("expr:" <+>) . ppValMd' pp) <$> (digveExpression gve) ]) -ppDIGlobalVariableExpression :: LLVM => DIGlobalVariableExpression -> Doc+ppDIGlobalVariableExpression :: Fmt DIGlobalVariableExpression ppDIGlobalVariableExpression = ppDIGlobalVariableExpression' ppLabel -ppDILexicalBlock' :: LLVM => (i -> Doc) -> DILexicalBlock' i -> Doc+ppDILexicalBlock' :: Fmt i -> Fmt (DILexicalBlock' i) ppDILexicalBlock' pp ct = "!DILexicalBlock" <> parens (mcommas [ (("scope:" <+>) . ppValMd' pp) <$> (dilbScope ct)@@ -1057,10 +1177,10 @@ , pure ("column:" <+> integral (dilbColumn ct)) ]) -ppDILexicalBlock :: LLVM => DILexicalBlock -> Doc+ppDILexicalBlock :: Fmt DILexicalBlock ppDILexicalBlock = ppDILexicalBlock' ppLabel -ppDILexicalBlockFile' :: LLVM => (i -> Doc) -> DILexicalBlockFile' i -> Doc+ppDILexicalBlockFile' :: Fmt i -> Fmt (DILexicalBlockFile' i) ppDILexicalBlockFile' pp lbf = "!DILexicalBlockFile" <> parens (mcommas [ pure ("scope:" <+> ppValMd' pp (dilbfScope lbf))@@ -1068,10 +1188,10 @@ , pure ("discriminator:" <+> integral (dilbfDiscriminator lbf)) ]) -ppDILexicalBlockFile :: LLVM => DILexicalBlockFile -> Doc+ppDILexicalBlockFile :: Fmt DILexicalBlockFile ppDILexicalBlockFile = ppDILexicalBlockFile' ppLabel -ppDILocalVariable' :: LLVM => (i -> Doc) -> DILocalVariable' i -> Doc+ppDILocalVariable' :: Fmt i -> Fmt (DILocalVariable' i) ppDILocalVariable' pp lv = "!DILocalVariable" <> parens (mcommas [ (("scope:" <+>) . ppValMd' pp) <$> (dilvScope lv)@@ -1081,13 +1201,18 @@ , (("type:" <+>) . ppValMd' pp) <$> (dilvType lv) , pure ("arg:" <+> integral (dilvArg lv)) , pure ("flags:" <+> integral (dilvFlags lv))+ , (("align:" <+>) . integral) <$> dilvAlignment lv+ , (("annotations:" <+>) . ppValMd' pp) <$> (dilvAnnotations lv) ]) -ppDILocalVariable :: LLVM => DILocalVariable -> Doc+ppDILocalVariable :: Fmt DILocalVariable ppDILocalVariable = ppDILocalVariable' ppLabel -- | See @writeDISubprogram@ in the LLVM source, in the file @AsmWriter.cpp@-ppDISubprogram' :: LLVM => (i -> Doc) -> DISubprogram' i -> Doc+--+-- Note that the textual syntax changed in LLVM 7, as the @retainedNodes@ field+-- was called @variables@ in previous LLVM versions.+ppDISubprogram' :: Fmt i -> Fmt (DISubprogram' i) ppDISubprogram' pp sp = "!DISubprogram" <> parens (mcommas [ (("scope:" <+>) . ppValMd' pp) <$> (dispScope sp)@@ -1108,63 +1233,115 @@ , (("unit:" <+>) . ppValMd' pp) <$> (dispUnit sp) , (("templateParams:" <+>) . ppValMd' pp) <$> (dispTemplateParams sp) , (("declaration:" <+>) . ppValMd' pp) <$> (dispDeclaration sp)- , (("variables:" <+>) . ppValMd' pp) <$> (dispVariables sp)+ , (("retainedNodes:" <+>) . ppValMd' pp) <$> (dispRetainedNodes sp) , (("thrownTypes:" <+>) . ppValMd' pp) <$> (dispThrownTypes sp)+ , (("annotations:" <+>) . ppValMd' pp) <$> (dispAnnotations sp) ]) -ppDISubprogram :: LLVM => DISubprogram -> Doc+ppDISubprogram :: Fmt DISubprogram ppDISubprogram = ppDISubprogram' ppLabel -ppDISubrange :: DISubrange -> Doc-ppDISubrange sr = "!DISubrange"- <> parens (commas [ "count:" <+> integral (disrCount sr)- , "lowerBound:" <+> integral (disrLowerBound sr)- ])+ppDISubrange' :: Fmt i -> Fmt (DISubrange' i)+ppDISubrange' pp sr =+ "!DISubrange"+ <> parens+ (mcommas+ -- LLVM < 7: count and lowerBound as signed int 64+ -- LLVM < 11: count as ValMd, lowerBound as signed in 64+ -- LLVM >= 11: ValMd of count, lowerBound, upperBound, and stride+ -- Valid through LLVM 17.+ -- See AST.hs description for more details on the structure.+ -- See https://github.com/llvm/llvm-project/blob/431969e/llvm/lib/IR/AsmWriter.cpp#L1888-L1927+ -- for more details on output generation.+ [+ (("count:" <+>) . ppInt64ValMd' (llvmVer >= 7) pp) <$> disrCount sr+ , (("lowerBound:" <+>) . ppInt64ValMd' (llvmVer >= 11) pp) <$> disrLowerBound sr+ , when' (llvmVer >= 11)+ $ (("upperBound:" <+>) . ppInt64ValMd' True pp) <$> disrUpperBound sr+ , when' (llvmVer >= 11)+ $ (("stride:" <+>) . ppInt64ValMd' True pp) <$> disrStride sr+ ]) -ppDISubroutineType' :: LLVM => (i -> Doc) -> DISubroutineType' i -> Doc+ppDISubrange :: Fmt DISubrange+ppDISubrange = ppDISubrange' ppLabel++ppDISubroutineType' :: Fmt i -> Fmt (DISubroutineType' i) ppDISubroutineType' pp st = "!DISubroutineType" <> parens (commas [ "flags:" <+> integral (distFlags st) , "types:" <+> fromMaybe "null" (ppValMd' pp <$> (distTypeArray st)) ]) -ppDISubroutineType :: LLVM => DISubroutineType -> Doc+ppDISubroutineType :: Fmt DISubroutineType ppDISubroutineType = ppDISubroutineType' ppLabel +ppDIArgList' :: Fmt i -> Fmt (DIArgList' i)+ppDIArgList' pp args = "!DIArgList"+ <> parens (commas (map (ppValMd' pp) (dialArgs args)))++ppDIArgList :: Fmt DIArgList+ppDIArgList = ppDIArgList' ppLabel+ -- Utilities ------------------------------------------------------------------- -ppBool :: Bool -> Doc+ppBool :: Fmt Bool ppBool b | b = "true" | otherwise = "false" -- | Build a variable-argument argument list.-ppArgList :: Bool -> [Doc] -> Doc+ppArgList :: Bool -> Fmt [Doc] ppArgList True ds = parens (commas (ds ++ ["..."])) ppArgList False ds = parens (commas ds) -integral :: Integral i => i -> Doc+integral :: Integral i => Fmt i integral = integer . fromIntegral -hex :: (Integral i, Show i) => i -> Doc+hex :: (Integral i, Show i) => Fmt i hex i = text (showHex i "0x") -opt :: Bool -> Doc -> Doc+opt :: Bool -> Fmt Doc opt True = id opt False = const empty -commas :: [Doc] -> Doc+-- | Print a ValMd' value as a plain signed integer (Int64) if possible. If the+-- ValMd' is not representable as an Int64, defer to ValMd' printing (if+-- canFallBack is True) or print nothing (for when a ValMd is not a valid+-- representation).++ppInt64ValMd' :: Bool -> Fmt i -> Fmt (ValMd' i)+ppInt64ValMd' canFallBack pp = go+ where go = \case+ ValMdValue tv+ | PrimType (Integer _) <- typedType tv+ , ValInteger i <- typedValue tv+ -> integer i -- 64 bits is the largest Int, so no conversion needed+ o@(ValMdDebugInfo (DebugInfoGlobalVariable gv)) ->+ case digvVariable gv of+ Nothing -> when' canFallBack $ ppValMd' pp o+ Just v -> go v+ o@(ValMdDebugInfo (DebugInfoGlobalVariableExpression expr)) ->+ case digveExpression expr of+ Nothing -> when' canFallBack $ ppValMd' pp o+ Just e -> go e+ ValMdDebugInfo (DebugInfoLocalVariable lv) ->+ integer $ fromIntegral $ dilvArg lv -- ??+ -- ValMdRef _idx -> mempty -- no table here to look this up...+ o -> when' canFallBack $ ppValMd' pp o+++commas :: Fmt [Doc] commas = fsep . punctuate comma -- | Helpful for all of the optional fields that appear in the -- metadata values-mcommas :: [Maybe Doc] -> Doc+mcommas :: Fmt [Maybe Doc] mcommas = commas . catMaybes -angles :: Doc -> Doc+angles :: Fmt Doc angles d = char '<' <> d <> char '>' -structBraces :: Doc -> Doc+structBraces :: Fmt Doc structBraces body = char '{' <+> body <+> char '}' -ppMaybe :: (a -> Doc) -> Maybe a -> Doc+ppMaybe :: Fmt a -> Fmt (Maybe a) ppMaybe = maybe empty
src/Text/LLVM/Parser.hs view
@@ -73,6 +73,7 @@ , angles (braces (PackedStruct <$> pTypeList) <|> spaced (pNumType Vector)) , string "opaque" >> return Opaque , PrimType <$> pPrimType+ , string "ptr" >> return PtrOpaque ] pTypeList :: Parser [Type]
+ src/Text/LLVM/Triple.hs view
@@ -0,0 +1,17 @@+{- |+Module : Text.LLVM.Triple+Description : AST, parsing, and printing of LLVM target triples.+License : BSD3+Maintainer : Langston Barrett+Stability : experimental+-}++module Text.LLVM.Triple+ ( module Text.LLVM.Triple.AST+ , module Text.LLVM.Triple.Parse+ , module Text.LLVM.Triple.Print+ ) where++import Text.LLVM.Triple.AST+import Text.LLVM.Triple.Parse+import Text.LLVM.Triple.Print
+ src/Text/LLVM/Triple/AST.hs view
@@ -0,0 +1,467 @@+{- |+Module : Text.LLVM.Triple.AST+Description : AST of LLVM target triples.+License : BSD3+Maintainer : Langston Barrett+Stability : experimental+-}++{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE StrictData #-}++module Text.LLVM.Triple.AST+ ( Arch(..)+ , SubArch(..)+ , Vendor(..)+ , OS(..)+ , Environment(..)+ , ObjectFormat(..)+ , TargetTriple(..)+ ) where++import Data.Data (Data)+import Data.Typeable (Typeable)+import GHC.Generics (Generic)++-- | The constructors of this type exactly mirror the LLVM @enum ArchType@,+-- including inconsistent labeling of endianness. Capitalization is taken from+-- the LLVM comments, which are reproduced below.+--+-- Last updated: LLVM 15.0.1:+-- https://github.com/llvm/llvm-project/blob/llvmorg-15.0.1/llvm/include/llvm/ADT/Triple.h#L46+data Arch+ = UnknownArch+ -- | ARM (little endian): arm armv.* xscale+ | ARM+ -- | ARM (big endian): armeb+ | ARMEB+ -- | AArch64 (little endian): aarch64+ | AArch64+ -- | AArch64 (big endian): aarch64_be+ | AArch64_BE+ -- | AArch64 (little endian) ILP32: aarch64_32+ | AArch64_32+ -- | ARC: Synopsys ARC+ | ARC+ -- | AVR: Atmel AVR microcontroller+ | AVR+ -- | eBPF or extended BPF or 64-bit BPF (little endian)+ | BPFEL+ -- | eBPF or extended BPF or 64-bit BPF (big endian)+ | BPFEB+ -- | CSKY: csky+ | CSKY+ -- | DXIL 32-bit DirectX bytecode+ | DXIL+ -- | Hexagon: hexagon+ | Hexagon+ -- | LoongArch (32-bit): loongarch32+ | LoongArch32+ -- | LoongArch (64-bit): loongarch64+ | LoongArch64+ -- | M68k: Motorola 680x0 family+ | M68k+ -- | MIPS: mips mipsallegrex mipsr6+ | MIPS+ -- | MIPSEL: mipsel mipsallegrexe mipsr6el+ | MIPSEL+ -- | MIPS64: mips64 mips64r6 mipsn32 mipsn32r6+ | MIPS64+ -- | MIPS64EL: mips64el mips64r6el mipsn32el mipsn32r6el+ | MIPS64EL+ -- | MSP430: msp430+ | MSP430+ -- | PPC: powerpc+ | PPC+ -- | PPCLE: powerpc (little endian)+ | PPCLE+ -- | PPC64: powerpc64 ppu+ | PPC64+ -- | PPC64LE: powerpc64le+ | PPC64LE+ -- | R600: AMD GPUs HD2XXX - HD6XXX+ | R600+ -- | AMDGCN: AMD GCN GPUs+ | AMDGCN+ -- | RISC-V (32-bit): riscv32+ | RISCV32+ -- | RISC-V (64-bit): riscv64+ | RISCV64+ -- | Sparc: sparc+ | Sparc+ -- | Sparcv9: Sparcv9+ | Sparcv9+ -- | Sparc: (endianness = little). NB: 'Sparcle' is a CPU variant+ | SparcEL+ -- | SystemZ: s390x+ | SystemZ+ -- | TCE (http://tce.cs.tut.fi/): tce+ | TCE+ -- | TCE little endian (http://tce.cs.tut.fi/): tcele+ | TCELE+ -- | Thumb (little endian): thumb thumbv.*+ | Thumb+ -- | Thumb (big endian): thumbeb+ | ThumbEB+ -- | X86: i[3-9]86+ | X86+ -- | X86-64: amd64 x86_64+ | X86_64+ -- | XCore: xcore+ | XCore+ -- | NVPTX: 32-bit+ | NVPTX+ -- | NVPTX: 64-bit+ | NVPTX64+ -- | le32: generic little-endian 32-bit CPU (PNaCl)+ | Le32+ -- | le64: generic little-endian 64-bit CPU (PNaCl)+ | Le64+ -- | AMDIL+ | AMDIL+ -- | AMDIL with 64-bit pointers+ | AMDIL64+ -- | AMD HSAIL+ | HSAIL+ -- | AMD HSAIL with 64-bit pointers+ | HSAIL64+ -- | SPIR: standard portable IR for OpenCL 32-bit version+ | SPIR+ -- | SPIR: standard portable IR for OpenCL 64-bit version+ | SPIR64+ -- | SPIR-V with 32-bit pointers+ | SPIRV32+ -- | SPIR-V with 64-bit pointers+ | SPIRV64+ -- | Kalimba: generic kalimba+ | Kalimba+ -- | SHAVE: Movidius vector VLIW processors+ | SHAVE+ -- | Lanai: Lanai 32-bit+ | Lanai+ -- | WebAssembly with 32-bit pointers+ | Wasm32+ -- | WebAssembly with 64-bit pointers+ | Wasm64+ -- | 32-bit RenderScript+ | RenderScript32 -- 32-bit RenderScript+ -- | 64-bit RenderScript+ | RenderScript64+ -- | NEC SX-Aurora Vector Engine+ | VE+ deriving (Bounded, Data, Eq, Enum, Generic, Ord, Read, Show, Typeable)++-- | A 'First'-like semigroup instance that simply drops the RHS, unless the LHS+-- is 'UnknownArch'.+instance Semigroup Arch where+ a <> UnknownArch{} = a+ UnknownArch{} <> b = b+ a <> _ = a++-- | @'mempty' == 'UnknownArch'@+instance Monoid Arch where+ mempty = UnknownArch++-- | The constructors of this type exactly mirror the LLVM @enum SubArchType@.+--+-- Last updated: LLVM 15.0.1:+-- https://github.com/llvm/llvm-project/blob/llvmorg-15.0.1/llvm/include/llvm/ADT/Triple.h#L110+data SubArch+ = NoSubArch+ | ARMSubArch_v9_3a+ | ARMSubArch_v9_2a+ | ARMSubArch_v9_1a+ | ARMSubArch_v9+ | ARMSubArch_v8_8a+ | ARMSubArch_v8_7a+ | ARMSubArch_v8_6a+ | ARMSubArch_v8_5a+ | ARMSubArch_v8_4a+ | ARMSubArch_v8_3a+ | ARMSubArch_v8_2a+ | ARMSubArch_v8_1a+ | ARMSubArch_v8+ | ARMSubArch_v8r+ | ARMSubArch_v8m_baseline+ | ARMSubArch_v8m_mainline+ | ARMSubArch_v8_1m_mainline+ | ARMSubArch_v7+ | ARMSubArch_v7em+ | ARMSubArch_v7m+ | ARMSubArch_v7s+ | ARMSubArch_v7k+ | ARMSubArch_v7ve+ | ARMSubArch_v6+ | ARMSubArch_v6m+ | ARMSubArch_v6k+ | ARMSubArch_v6t2+ | ARMSubArch_v5+ | ARMSubArch_v5te+ | ARMSubArch_v4t++ | AArch64SubArch_arm64e++ | KalimbaSubArch_v3+ | KalimbaSubArch_v4+ | KalimbaSubArch_v5++ | MipsSubArch_r6++ | PPCSubArch_spe++ | SPIRVSubArch_v10+ | SPIRVSubArch_v11+ | SPIRVSubArch_v12+ | SPIRVSubArch_v13+ | SPIRVSubArch_v14+ | SPIRVSubArch_v15+ deriving (Bounded, Data, Enum, Eq, Generic, Ord, Read, Show, Typeable)++-- | A 'First'-like semigroup instance that simply drops the RHS, unless the LHS+-- is 'NoSubArch'.+instance Semigroup SubArch where+ a <> NoSubArch{} = a+ NoSubArch{} <> b = b+ a <> _ = a++-- | @'mempty' == 'NoSubArch'@+instance Monoid SubArch where+ mempty = NoSubArch++-- | The constructors of this type exactly mirror the LLVM @enum VendorType@,+-- including ordering and grouping.+--+-- Last updated: LLVM 15.0.1:+-- https://github.com/llvm/llvm-project/blob/llvmorg-15.0.1/llvm/include/llvm/ADT/Triple.h#L162+data Vendor+ = UnknownVendor+ | Apple+ | PC+ | SCEI+ | Freescale+ | IBM+ | ImaginationTechnologies+ | MipsTechnologies+ | NVIDIA+ | CSR+ | Myriad+ | AMD+ | Mesa+ | SUSE+ | OpenEmbedded+ deriving (Bounded, Data, Enum, Eq, Generic, Ord, Read, Show, Typeable)++-- | A 'First'-like semigroup instance that simply drops the RHS, unless the LHS+-- is 'UnknownVendor'.+instance Semigroup Vendor where+ a <> UnknownVendor{} = a+ UnknownVendor{} <> b = b+ a <> _ = a++-- | @'mempty' == 'UnknownVendor'@+instance Monoid Vendor where+ mempty = UnknownVendor++-- | The constructors of this type exactly mirror the LLVM @enum OSType@,+-- including ordering and grouping.+--+-- End-of-line comments from LLVM are reproduced as constructor comments.+--+-- Last updated: LLVM 15.0.1:+-- https://github.com/llvm/llvm-project/blob/llvmorg-15.0.1/llvm/include/llvm/ADT/Triple.h#L181+data OS+ = UnknownOS+ | Ananas+ | CloudABI+ | Darwin+ | DragonFly+ | FreeBSD+ | Fuchsia+ | IOS+ | KFreeBSD+ | Linux+ -- | PS3+ | Lv2+ | MacOSX+ | NetBSD+ | OpenBSD+ | Solaris+ | Win32+ | ZOS+ | Haiku+ | Minix+ | RTEMS+ -- | Native Client+ | NaCl+ | AIX+ -- | NVIDIA CUDA+ | CUDA+ -- | NVIDIA OpenCL+ | NVCL+ -- | AMD HSA Runtime+ | AMDHSA+ | PS4+ | PS5+ | ELFIAMCU+ -- | Apple tvOS+ | TvOS+ -- | Apple watchOS+ | WatchOS+ -- | Apple DriverKit+ | DriverKit+ | Mesa3D+ | Contiki+ -- | AMD PAL Runtime+ | AMDPAL+ -- | HermitCore Unikernel/Multikernel+ | HermitCore+ -- | GNU/Hurd+ | Hurd+ -- | Experimental WebAssembly OS+ | WASI+ | Emscripten+ -- | DirectX ShaderModel+ | ShaderModel+ deriving (Bounded, Data, Enum, Eq, Generic, Ord, Read, Show, Typeable)++-- | A 'First'-like semigroup instance that simply drops the RHS, unless the LHS+-- is 'UnknownOS'.+instance Semigroup OS where+ a <> UnknownOS{} = a+ UnknownOS{} <> b = b+ a <> _ = a++-- | @'mempty' == 'UnknownOS'@+instance Monoid OS where+ mempty = UnknownOS++-- | The constructors of this type exactly mirror the LLVM @enum+-- EnvironmentType@, including ordering and grouping.+--+-- End-of-line comments from LLVM are reproduced as constructor comments.+--+-- Last updated: LLVM 15.0.1:+-- https://github.com/llvm/llvm-project/blob/llvmorg-15.0.1/llvm/include/llvm/ADT/Triple.h#L224+data Environment+ = UnknownEnvironment++ | GNU+ | GNUABIN32+ | GNUABI64+ | GNUEABI+ | GNUEABIHF+ | GNUX32+ | GNUILP32+ | CODE16+ | EABI+ | EABIHF+ | Android+ | Musl+ | MuslEABI+ | MuslEABIHF+ | MuslX32++ | MSVC+ | Itanium+ | Cygnus+ | CoreCLR+ -- | Simulator variants of other systems e.g. Apple's iOS+ | Simulator+ -- | Mac Catalyst variant of Apple's iOS deployment target.+ | MacABI++ | Pixel+ | Vertex+ | Geometry+ | Hull+ | Domain+ | Compute+ | Library+ | RayGeneration+ | Intersection+ | AnyHit+ | ClosestHit+ | Miss+ | Callable+ | Mesh+ | Amplification+ deriving (Bounded, Data, Enum, Eq, Generic, Ord, Read, Show, Typeable)++-- | A 'First'-like semigroup instance that simply drops the RHS, unless the LHS+-- is 'UnknownEnvironment'.+instance Semigroup Environment where+ a <> UnknownEnvironment{} = a+ UnknownEnvironment{} <> b = b+ a <> _ = a++-- | @'mempty' == 'UnknownEnvironment'@+instance Monoid Environment where+ mempty = UnknownEnvironment++-- | The constructors of this type exactly mirror the LLVM @enum+-- ObjectFormatType@, including ordering.+--+-- Last updated: LLVM 15.0.1:+-- https://github.com/llvm/llvm-project/blob/llvmorg-15.0.1/llvm/include/llvm/ADT/Triple.h#L269+data ObjectFormat+ = UnknownObjectFormat+ | COFF+ | DXContainer+ | ELF+ | GOFF+ | MachO+ | SPIRV+ | Wasm+ | XCOFF+ deriving (Bounded, Data, Enum, Eq, Generic, Ord, Read, Show, Typeable)++-- | A 'First'-like semigroup instance that simply drops the RHS, unless the LHS+-- is 'UnknownObjectFormat'.+instance Semigroup ObjectFormat where+ a <> UnknownObjectFormat{} = a+ UnknownObjectFormat{} <> b = b+ a <> _ = a++-- | @'mempty' == 'UnknownObjectFormat'@+instance Monoid ObjectFormat where+ mempty = UnknownObjectFormat++-- | More like a sextuple than a triple, if you think about it.+--+-- The LLVM version of this holds onto the un-normalized string representation.+-- We discard it.+data TargetTriple+ = TargetTriple+ { ttArch :: Arch+ , ttSubArch :: SubArch+ , ttVendor :: Vendor+ , ttOS :: OS+ , ttEnv :: Environment+ , ttObjFmt :: ObjectFormat+ }+ deriving (Bounded, Data, Eq, Generic, Ord, Read, Show, Typeable)++-- | Combines fields pointwise.+instance Semigroup TargetTriple where+ tt <> tt' =+ TargetTriple+ { ttArch = ttArch tt <> ttArch tt'+ , ttSubArch = ttSubArch tt <> ttSubArch tt'+ , ttVendor = ttVendor tt <> ttVendor tt'+ , ttOS = ttOS tt <> ttOS tt'+ , ttEnv = ttEnv tt <> ttEnv tt'+ , ttObjFmt = ttObjFmt tt <> ttObjFmt tt'+ }++-- | Pointwise 'mempty'.+instance Monoid TargetTriple where+ mempty =+ TargetTriple+ { ttArch = mempty+ , ttSubArch = mempty+ , ttVendor = mempty+ , ttOS = mempty+ , ttEnv = mempty+ , ttObjFmt = mempty+ }
+ src/Text/LLVM/Triple/Parse.hs view
@@ -0,0 +1,294 @@+{- |+Module : Text.LLVM.Triple.Parse+Description : Parsing of LLVM target triples.+License : BSD3+Maintainer : Langston Barrett+Stability : experimental++The declarations appear in this module in the same order as in the LLVM source.+-}++{- Note [Implementation]++The very simplest parsing functions are implemented with the 'LookupTable'+structure. For anything more complex, we endeavor to closely mirror the+structure of LLVM's implementation. This will make the code more maintainable+when updating to newer versions of LLVM.++-}++{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE MultiWayIf #-}++module Text.LLVM.Triple.Parse+ ( parseArch+ , parseVendor+ , parseOS+ , parseEnv+ , parseObjFmt+ , parseSubArch+ , parseTriple+ ) where++import qualified Data.List as List++import qualified MonadLib as M+import qualified MonadLib.Monads as M++import Text.LLVM.Triple.AST+import qualified Text.LLVM.Triple.Print as Print+import Text.LLVM.Triple.Parse.LookupTable+import qualified Text.LLVM.Triple.Parse.ARM as ARM++-- | @llvm::parseArch@+--+-- https://github.com/llvm/llvm-project/blob/llvmorg-15.0.1/llvm/lib/Support/Triple.cpp#L442+parseArch :: String -> Arch+parseArch s =+ let mArch =+ -- See Note [Implementation] for the reasoning behind the strange structure.+ --+ -- It would be easy to forget to add patterns here when adding a new+ -- constructor to Arch, but we have exhaustive print-then-parse+ -- roundtrip tests to mitigate this risk.+ if | cases ["i386", "i486", "i586", "i686"] -> X86+ | cases ["i786", "i886", "i986"] -> X86+ | cases ["amd64", "x86_64", "x86_64h"] -> X86_64+ | cases ["powerpc", "powerpcspe", "ppc", "ppc32"] -> PPC+ | cases ["powerpcle", "ppcle", "ppc32le"] -> PPCLE+ | cases ["powerpc64", "ppu", "ppc64"] -> PPC64+ | cases ["powerpc64le", "ppc64le"] -> PPC64LE+ | cases ["xscale"] -> ARM+ | cases ["xscaleeb"] -> ARMEB+ | cases ["aarch64"] -> AArch64+ | cases ["aarch64_be"] -> AArch64_BE+ | cases ["aarch64_32"] -> AArch64_32+ | cases ["arc"] -> ARC+ | cases ["arm64"] -> AArch64+ | cases ["arm64_32"] -> AArch64_32+ | cases ["arm64e"] -> AArch64+ | cases ["arm"] -> ARM+ | cases ["armeb"] -> ARMEB+ | cases ["thumb"] -> Thumb+ | cases ["thumbeb"] -> ThumbEB+ | cases ["avr"] -> AVR+ | cases ["m68k"] -> M68k+ | cases ["msp430"] -> MSP430+ | cases ["mips", "mipseb", "mipsallegrex", "mipsisa32r6"+ , "mipsr6"] -> MIPS+ | cases ["mipsel", "mipsallegrexel", "mipsisa32r6el", "mipsr6el"] -> MIPSEL+ | cases ["mips64", "mips64eb", "mipsn32", "mipsisa64r6"+ , "mips64r6", "mipsn32r6"] -> MIPS64+ | cases ["mips64el", "mipsn32el", "mipsisa64r6el", "mips64r6el"+ , "mipsn32r6el"] -> MIPS64EL+ | cases ["r600"] -> R600+ | cases ["amdgcn"] -> AMDGCN+ | cases ["riscv32"] -> RISCV32+ | cases ["riscv64"] -> RISCV64+ | cases ["hexagon"] -> Hexagon+ | cases ["s390x", "systemz"] -> SystemZ+ | cases ["sparc"] -> Sparc+ | cases ["sparcel"] -> SparcEL+ | cases ["sparcv9", "sparc64"] -> Sparcv9+ | cases ["tce"] -> TCE+ | cases ["tcele"] -> TCELE+ | cases ["xcore"] -> XCore+ | cases ["nvptx"] -> NVPTX+ | cases ["nvptx64"] -> NVPTX64+ | cases ["le32"] -> Le32+ | cases ["le64"] -> Le64+ | cases ["amdil"] -> AMDIL+ | cases ["amdil64"] -> AMDIL64+ | cases ["hsail"] -> HSAIL+ | cases ["hsail64"] -> HSAIL64+ | cases ["spir"] -> SPIR+ | cases ["spir64"] -> SPIR64+ | cases ["spirv32", "spirv32v1.0", "spirv32v1.1", "spirv32v1.2"+ , "spirv32v1.3", "spirv32v1.4", "spirv32v1.5"] -> SPIRV32+ | cases ["spirv64", "spirv64v1.0", "spirv64v1.1", "spirv64v1.2"+ , "spirv64v1.3", "spirv64v1.4", "spirv64v1.5"] -> SPIRV64+ | archPfx Kalimba -> Kalimba+ | cases ["lanai"] -> Lanai+ | cases ["renderscript32"] -> RenderScript32+ | cases ["renderscript64"] -> RenderScript64+ | cases ["shave"] -> SHAVE+ | cases ["ve"] -> VE+ | cases ["wasm32"] -> Wasm32+ | cases ["wasm64"] -> Wasm64+ | cases ["csky"] -> CSKY+ | cases ["loongarch32"] -> LoongArch32+ | cases ["loongarch64"] -> LoongArch64+ | cases ["dxil"] -> DXIL+ | otherwise -> UnknownArch+ in case mArch of+ UnknownArch ->+ if | archPfx ARM || archPfx Thumb || archPfx AArch64 ->+ ARM.parseARMArch (ARM.ArchName s)+ | "bpf" `List.isPrefixOf` s -> parseBPFArch s+ | otherwise -> UnknownArch+ arch -> arch+ where+ cases = any (== s)+ archPfx arch = Print.archName arch `List.isPrefixOf` s++ -- https://github.com/llvm/llvm-project/blob/llvmorg-15.0.1/llvm/lib/Support/Triple.cpp#L292+ parseBPFArch arch =+ if arch == "bpf"+ -- The way that LLVM parses the arch for BPF depends on the endianness of+ -- the host in this case, which feels deeply wrong. We don't do that, not+ -- least since we're not in IO. We default to little-endian instead.+ then BPFEL+ else if | arch == "bpf_be" || arch == "bpfeb" -> BPFEB+ | arch == "bpf_le" || arch == "bpfel" -> BPFEL+ | otherwise -> UnknownArch++-- | @llvm::parseVendor@+--+-- https://github.com/llvm/llvm-project/blob/llvmorg-15.0.1/llvm/lib/Support/Triple.cpp#L529+parseVendor :: String -> Vendor+parseVendor = lookupWithDefault table UnknownVendor+ where table = enumTable Print.vendorName++-- | @llvm::parseOS@+--+-- https://github.com/llvm/llvm-project/blob/llvmorg-15.0.1/llvm/lib/Support/Triple.cpp#L549+parseOS :: String -> OS+parseOS = lookupByPrefixWithDefault table UnknownOS+ where table = enumTable Print.osName++-- | @llvm::parseEnvironment@+--+-- https://github.com/llvm/llvm-project/blob/llvmorg-15.0.1/llvm/lib/Support/Triple.cpp#L593+parseEnv :: String -> Environment+parseEnv = lookupByPrefixWithDefault table UnknownEnvironment+ where table = enumTable Print.envName++-- | @llvm::parseFormat@+--+-- https://github.com/llvm/llvm-project/blob/llvmorg-15.0.1/llvm/lib/Support/Triple.cpp#L634+parseObjFmt :: String -> ObjectFormat+parseObjFmt = lookupBySuffixWithDefault table UnknownObjectFormat+ where table = enumTable Print.objFmtName++-- | @llvm::parseSubArch@+--+-- https://github.com/llvm/llvm-project/blob/llvmorg-15.0.1/llvm/lib/Support/Triple.cpp#L648+parseSubArch :: String -> SubArch+parseSubArch subArchName =+ if | startsWith "mips" && (endsWith "r6el" || endsWith "r6") -> MipsSubArch_r6++ | subArchName == "powerpcspe" -> PPCSubArch_spe++ | subArchName == "arm64e" -> AArch64SubArch_arm64e++ | startsWith "arm64e" -> AArch64SubArch_arm64e++ | startsWith "spirv" ->+ if | endsWith "v1.0" -> SPIRVSubArch_v10+ | endsWith "v1.1" -> SPIRVSubArch_v11+ | endsWith "v1.2" -> SPIRVSubArch_v12+ | endsWith "v1.3" -> SPIRVSubArch_v13+ | endsWith "v1.4" -> SPIRVSubArch_v14+ | endsWith "v1.5" -> SPIRVSubArch_v15+ | otherwise -> NoSubArch+ | otherwise ->+ case ARM.parseArch <$> armSubArch of+ Nothing ->+ if | endsWith "kalimba3" -> KalimbaSubArch_v3+ | endsWith "kalimba4" -> KalimbaSubArch_v4+ | endsWith "kalimba5" -> KalimbaSubArch_v5+ | otherwise -> NoSubArch+ Just armArch ->+ if | armArch == ARM.ARMV4 -> NoSubArch+ | armArch == ARM.ARMV4T -> ARMSubArch_v4t+ | armArch == ARM.ARMV5T -> ARMSubArch_v5+ | armArch == ARM.ARMV5TE ||+ armArch == ARM.IWMMXT ||+ armArch == ARM.IWMMXT2 ||+ armArch == ARM.XSCALE ||+ armArch == ARM.ARMV5TEJ -> ARMSubArch_v5te+ | armArch == ARM.ARMV6 -> ARMSubArch_v6+ | armArch == ARM.ARMV6K ||+ armArch == ARM.ARMV6KZ -> ARMSubArch_v6k+ | armArch == ARM.ARMV6T2 -> ARMSubArch_v6t2+ | armArch == ARM.ARMV6M -> ARMSubArch_v6m+ | armArch == ARM.ARMV7A ||+ armArch == ARM.ARMV7R -> ARMSubArch_v7+ | armArch == ARM.ARMV7VE -> ARMSubArch_v7ve+ | armArch == ARM.ARMV7K -> ARMSubArch_v7k+ | armArch == ARM.ARMV7M -> ARMSubArch_v7m+ | armArch == ARM.ARMV7S -> ARMSubArch_v7s+ | armArch == ARM.ARMV7EM -> ARMSubArch_v7em+ | armArch == ARM.ARMV8A -> ARMSubArch_v8+ | armArch == ARM.ARMV8_1A -> ARMSubArch_v8_1a+ | armArch == ARM.ARMV8_2A -> ARMSubArch_v8_2a+ | armArch == ARM.ARMV8_3A -> ARMSubArch_v8_3a+ | armArch == ARM.ARMV8_4A -> ARMSubArch_v8_4a+ | armArch == ARM.ARMV8_5A -> ARMSubArch_v8_5a+ | armArch == ARM.ARMV8_6A -> ARMSubArch_v8_6a+ | armArch == ARM.ARMV8_7A -> ARMSubArch_v8_7a+ | armArch == ARM.ARMV8_8A -> ARMSubArch_v8_8a+ | armArch == ARM.ARMV9A -> ARMSubArch_v9+ | armArch == ARM.ARMV9_1A -> ARMSubArch_v9_1a+ | armArch == ARM.ARMV9_2A -> ARMSubArch_v9_2a+ | armArch == ARM.ARMV9_3A -> ARMSubArch_v9_3a+ | armArch == ARM.ARMV8R -> ARMSubArch_v8r+ | armArch == ARM.ARMV8MBaseline -> ARMSubArch_v8m_baseline+ | armArch == ARM.ARMV8MMainline -> ARMSubArch_v8m_mainline+ | armArch == ARM.ARMV8_1MMainline -> ARMSubArch_v8_1m_mainline+ | otherwise -> NoSubArch+ where+ startsWith = (`List.isPrefixOf` subArchName)+ endsWith = (`List.isSuffixOf` subArchName)+ armSubArch = ARM.getCanonicalArchName (ARM.ArchName subArchName)++-- | @llvm::Triple::getDefaultFormat@+--+-- TODO(#97): Implement me!+defaultObjFmt :: TargetTriple -> ObjectFormat+defaultObjFmt _tt = UnknownObjectFormat++-- | @llvm::Triple::Triple@+--+-- https://github.com/llvm/llvm-project/blob/llvmorg-15.0.1/llvm/lib/Support/Triple.cpp#L869+parseTriple :: String -> TargetTriple+parseTriple str =+ execState (split '-' str) $ do+ let pop def f =+ M.sets $+ \case+ (hd:rest) -> (f hd, rest)+ [] -> (def, [])+ (arch, subArch) <-+ pop (UnknownArch, NoSubArch) (\s -> (parseArch s, parseSubArch s))+ vendor <- pop UnknownVendor parseVendor+ os <- pop UnknownOS parseOS+ (env, objFmt) <-+ pop (UnknownEnvironment, UnknownObjectFormat) (\s -> (parseEnv s, parseObjFmt s))+ let tt =+ TargetTriple+ { ttArch = arch+ , ttSubArch = subArch+ , ttVendor = vendor+ , ttOS = os+ , ttEnv = env+ , ttObjFmt = objFmt+ }+ return (tt { ttObjFmt =+ if ttObjFmt tt == UnknownObjectFormat+ then defaultObjFmt tt+ else ttObjFmt tt+ })+ where++ -- > split '-' "foo-bar" == ["foo", "bar"]+ split :: Char -> String -> [String]+ split splitter =+ foldr (\c strs -> if c == splitter then ([]:strs) else push c strs) [[]]+ where+ push c [] = [[c]]+ push c (s:strs) = (c:s):strs++ -- Not in MonadLib...+ execState s = fst . M.runState s
+ src/Text/LLVM/Triple/Parse/ARM.hs view
@@ -0,0 +1,347 @@+{- |+Module : Text.LLVM.Triple.Parse.ARM+Description : ARM utilities used in target triple parsing.+License : BSD3+Maintainer : Langston Barrett+Stability : experimental++This module is not exposed as part of the library API.+-}++{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE MultiWayIf #-}+{-# LANGUAGE StrictData #-}++module Text.LLVM.Triple.Parse.ARM+ ( ArchName(..)+ -- * Endianness+ , EndianKind(..)+ , parseEndianKind+ -- * ISA+ , ISAKind(..)+ , parseISAKind+ -- * Arch+ , getCanonicalArchName+ , parseARMArch+ , ARMArch(..)+ , armArchName+ , parseArch+ ) where++import qualified Data.Char as Char+import Control.Monad (liftM2, when)+import qualified MonadLib as M+import qualified MonadLib.Monads as M+import qualified Data.List as List++import Text.LLVM.Triple.AST+import qualified Text.LLVM.Triple.Parse.LookupTable as Lookup++-- | The "arch" portion of a target triple+newtype ArchName = ArchName { getArchName :: String }++--------------------------------------------------------------------------------+-- Endianness++-- | @llvm::EndianKind@+--+-- https://github.com/llvm/llvm-project/blob/llvmorg-15.0.1/llvm/include/llvm/Support/ARMTargetParser.h#L166+data EndianKind+ = Little+ | Big+ deriving (Bounded, Enum, Eq, Ord)++-- | @llvm::ARM::parseArchEndian@+--+-- https://github.com/llvm/llvm-project/blob/llvmorg-15.0.1/llvm/lib/Support/ARMTargetParser.cpp#L248+parseEndianKind :: ArchName -> Maybe EndianKind+parseEndianKind (ArchName arch) =+ if | hasPfx "armeb" || hasPfx "thumbeb" || hasPfx "aarch64_be" -> Just Big+ | hasPfx "arm" || hasPfx "thumb" ->+ if hasSfx "eb"+ then Just Big+ else Just Little+ | hasPfx "aarch64" || hasPfx "aarch64_32" -> Just Little+ | otherwise -> Nothing+ where+ hasPfx = (`List.isPrefixOf` arch)+ hasSfx = (`List.isSuffixOf` arch)++--------------------------------------------------------------------------------+-- ISA++-- | @llvm::ISAKind@+--+-- https://github.com/llvm/llvm-project/blob/llvmorg-15.0.1/llvm/include/llvm/Support/ARMTargetParser.h#L162+data ISAKind+ = ISAArm+ | ISAThumb+ | ISAAArch64+ deriving (Bounded, Enum, Eq, Ord)++-- | @llvm::ARM::parseArchISA@+--+-- https://github.com/llvm/llvm-project/blob/llvmorg-15.0.1/llvm/lib/Support/ARMTargetParser.cpp#L267+parseISAKind :: ArchName -> Maybe ISAKind+parseISAKind (ArchName arch) = Lookup.lookupByPrefix arch table+ where+ table =+ Lookup.makeTable+ [ ("aarch64", ISAAArch64)+ , ("arm64", ISAAArch64)+ , ("thumb", ISAThumb)+ , ("arm", ISAArm)+ ]++--------------------------------------------------------------------------------+-- Arch++-- | @llvm::ARM::getArchSynonym@+getArchSynonym :: ArchName -> ArchName+getArchSynonym (ArchName arch) =+ ArchName $+ if | cases ["v5"] -> "v5t"+ | cases ["v5e"] -> "v5te"+ | cases ["v6j"] -> "v6"+ | cases ["v6hl"] -> "v6k"+ | cases ["v6m", "v6sm", "v6s-m"] -> "v6-m"+ | cases ["v6z", "v6zk"] -> "v6kz"+ | cases ["v7", "v7a", "v7hl", "v7l"] -> "v7-a"+ | cases ["v7r"] -> "v7-r"+ | cases ["v7m"] -> "v7-m"+ | cases ["v7em"] -> "v7e-m"+ | cases ["v8", "v8a", "v8l", "aarch64", "arm64"] -> "v8-a"+ | cases ["v8.1a"] -> "v8.1-a"+ | cases ["v8.2a"] -> "v8.2-a"+ | cases ["v8.3a"] -> "v8.3-a"+ | cases ["v8.4a"] -> "v8.4-a"+ | cases ["v8.5a"] -> "v8.5-a"+ | cases ["v8.6a"] -> "v8.6-a"+ | cases ["v8.7a"] -> "v8.7-a"+ | cases ["v8.8a"] -> "v8.8-a"+ | cases ["v8r"] -> "v8-r"+ | cases ["v9", "v9a"] -> "v9-a"+ | cases ["v9.1a"] -> "v9.1-a"+ | cases ["v9.2a"] -> "v9.2-a"+ | cases ["v9.3a"] -> "v9.3-a"+ | cases ["v8m.base"] -> "v8-m.base"+ | cases ["v8m.main"] -> "v8-m.main"+ | cases ["v8.1m.main"] -> "v8.1-m.main"+ | otherwise -> arch+ where+ cases = any (== arch)++data CanonicalArchNameState+ = CanonicalArchNameState+ { offset :: Int+ , archStr :: String -- ^ @A@ in the LLVM+ }++-- | @llvm::ARM::getCanonicalArchName@+--+-- https://github.com/llvm/llvm-project/blob/llvmorg-15.0.1/llvm/lib/Support/ARMTargetParser.cpp#L295+getCanonicalArchName :: ArchName -> Maybe ArchName+getCanonicalArchName (ArchName arch) =+ -- See Note [Implementation] for the reasoning behind the strange structure.+ --+ -- Could probably be translated even more directly using ContT, but that feels+ -- like a bit much.+ execState (CanonicalArchNameState 0 arch) $ do+ ifM (liftM2 (&&) (startsWith "aarch64") (contains "eb")) (return Nothing) $ do+ whenM (startsWith "arm64_32") $+ setOffset 8+ whenM (startsWith "arm64e") $+ setOffset 6+ whenM (startsWith "arm64") $+ setOffset 5+ whenM (startsWith "aarch64_32") $+ setOffset 10+ whenM (startsWith "arm") $+ setOffset 3+ whenM (startsWith "thumb") $+ setOffset 5+ whenM (startsWith "aarch64") $ do+ setOffset 7+ whenM ((== "_be") <$> archOffSubstr 3) $+ addOffset 3++ off <- offset <$> M.get+ sub <- archOffSubstr 2+ when (off /= npos && sub == "eb") $+ addOffset 2+ whenM (endsWith "eb") $ do+ changeArch (\arch' -> substr 0 (length arch' - 2) arch')+ off' <- offset <$> M.get+ when (off' /= npos) $+ changeArch (drop off')++ arch' <- archStr <$> M.get+ if | length arch' == 0 -> return Nothing+ | off' /= npos && length arch' > 2 &&+ (take 1 arch' /= "v" || not (all Char.isDigit (substr 1 1 arch'))) ->+ return Nothing+ | off' /= npos && "eb" `List.isInfixOf` arch' -> return Nothing+ | otherwise -> return (Just (ArchName arch'))+ where+ npos = 0++ ifM b thn els = b >>= \b' -> if b' then thn else els+ whenM b k = ifM b k (return ())+ startsWith pfx = (pfx `List.isPrefixOf`) . archStr <$> M.get+ endsWith sfx = (sfx `List.isSuffixOf`) . archStr <$> M.get+ contains ifx = (ifx `List.isInfixOf`) . archStr <$> M.get++ substr start sz = take sz . drop start+ archSubstr begin sz = substr begin sz . archStr <$> M.get+ archOffSubstr sz = do+ off <- offset <$> M.get+ archSubstr off sz++ changeOffset f = do+ s <- M.get+ M.set (s { offset = f (offset s) })+ addOffset n = changeOffset (n+)+ setOffset n = changeOffset (const n)++ changeArch f = M.set . (\s -> s { archStr = f (archStr s) }) =<< M.get++ -- Not in MonadLib...+ execState s = fst . M.runState s++-- | @llvm::parseARMArch@+--+-- https://github.com/llvm/llvm-project/blob/llvmorg-15.0.1/llvm/lib/Support/Triple.cpp#L377+parseARMArch :: ArchName -> Arch+parseARMArch archName =+ let+ isa = parseISAKind archName+ endian = parseEndianKind archName+ arch =+ case endian of+ Just Little ->+ case isa of+ Just ISAArm -> ARM+ Just ISAThumb -> Thumb+ Just ISAAArch64 -> AArch64+ Nothing -> UnknownArch+ Just Big ->+ case isa of+ Just ISAArm -> ARMEB+ Just ISAThumb -> ThumbEB+ Just ISAAArch64 -> AArch64_BE+ Nothing -> UnknownArch+ Nothing -> UnknownArch+ mArchName = getCanonicalArchName archName+ in case mArchName of+ Nothing -> UnknownArch+ Just (ArchName archNm) ->+ if | isa == Just ISAThumb &&+ ("v2" `List.isPrefixOf` archNm || "v3" `List.isPrefixOf` archNm) -> UnknownArch+ -- TODO(#98): LLVM has one more check here involving the "arch+ -- profile" that's not yet implemented here... Probably not a big+ -- deal because this case is only executed when the target arch+ -- doesn't match the "canonical" versions like "arm", "thumb", and+ -- "aarch64".+ | otherwise -> arch++-- | See LLVM's @ARMTargetParser.def@+--+-- https://github.com/llvm/llvm-project/blob/llvmorg-15.0.1/llvm/include/llvm/Support/ARMTargetParser.def#L48+data ARMArch+ = ARMArchInvalid+ | ARMV2+ | ARMV2A+ | ARMV3+ | ARMV3M+ | ARMV4+ | ARMV4T+ | ARMV5T+ | ARMV5TE+ | ARMV5TEJ+ | ARMV6+ | ARMV6K+ | ARMV6T2+ | ARMV6KZ+ | ARMV6M+ | ARMV7A+ | ARMV7VE+ | ARMV7R+ | ARMV7M+ | ARMV7EM+ | ARMV8A+ | ARMV8_1A+ | ARMV8_2A+ | ARMV8_3A+ | ARMV8_4A+ | ARMV8_5A+ | ARMV8_6A+ | ARMV8_7A+ | ARMV8_8A+ | ARMV9A+ | ARMV9_1A+ | ARMV9_2A+ | ARMV9_3A+ | ARMV8R+ | ARMV8MBaseline+ | ARMV8MMainline+ | ARMV8_1MMainline+ | IWMMXT+ | IWMMXT2+ | XSCALE+ | ARMV7S+ | ARMV7K+ deriving (Bounded, Enum, Eq, Ord)++armArchName :: ARMArch -> String+armArchName =+ \case+ ARMArchInvalid -> "invalid"+ ARMV2 -> "armv2"+ ARMV2A -> "armv2a"+ ARMV3 -> "armv3"+ ARMV3M -> "armv3m"+ ARMV4 -> "armv4"+ ARMV4T -> "armv4t"+ ARMV5T -> "armv5t"+ ARMV5TE -> "armv5te"+ ARMV5TEJ -> "armv5tej"+ ARMV6 -> "armv6"+ ARMV6K -> "armv6k"+ ARMV6T2 -> "armv6t2"+ ARMV6KZ -> "armv6kz"+ ARMV6M -> "armv6-m"+ ARMV7A -> "armv7-a"+ ARMV7VE -> "armv7ve"+ ARMV7R -> "armv7-r"+ ARMV7M -> "armv7-m"+ ARMV7EM -> "armv7e-m"+ ARMV8A -> "armv8-a"+ ARMV8_1A -> "armv8.1-a"+ ARMV8_2A -> "armv8.2-a"+ ARMV8_3A -> "armv8.3-a"+ ARMV8_4A -> "armv8.4-a"+ ARMV8_5A -> "armv8.5-a"+ ARMV8_6A -> "armv8.6-a"+ ARMV8_7A -> "armv8.7-a"+ ARMV8_8A -> "armv8.8-a"+ ARMV9A -> "armv9-a"+ ARMV9_1A -> "armv9.1-a"+ ARMV9_2A -> "armv9.2-a"+ ARMV9_3A -> "armv9.3-a"+ ARMV8R -> "armv8-r"+ ARMV8MBaseline -> "armv8-m.base"+ ARMV8MMainline -> "armv8-m.main"+ ARMV8_1MMainline -> "armv8.1-m.main"+ IWMMXT -> "iwmmxt"+ IWMMXT2 -> "iwmmxt2"+ XSCALE -> "xscale"+ ARMV7S -> "armv7s"+ ARMV7K -> "armv7k"++-- | @llvm::ARM::parseArch@+parseArch :: ArchName -> ARMArch+parseArch arch =+ let ArchName syn = getArchSynonym arch+ table = Lookup.enumTable armArchName+ in Lookup.lookupBySuffixWithDefault table ARMArchInvalid syn
+ src/Text/LLVM/Triple/Parse/LookupTable.hs view
@@ -0,0 +1,77 @@+{- |+Module : Text.LLVM.Triple.Parse.LookupTable+Description : Helpers for parsing a finite set of strings.+License : BSD3+Maintainer : Langston Barrett+Stability : experimental++This module is not exposed as part of the library API.+-}++{-# LANGUAGE TupleSections #-}++module Text.LLVM.Triple.Parse.LookupTable+ ( -- * Construction+ LookupTable+ , makeTable+ , enumTable+ , enumTableVariants+ -- * Queries+ , lookupBy+ , lookup+ , lookupByPrefix+ , lookupByWithDefault+ , lookupWithDefault+ , lookupByPrefixWithDefault+ , lookupBySuffixWithDefault+ ) where++import Prelude hiding (lookup)+import qualified Data.Maybe as Maybe+import qualified Data.List as List++--------------------------------------------------------------------------------+-- Construction++-- | A table from constrant strings to values, to be used in parsing a finite+-- set of possibilities. Could be replaced by a fancier data structure, but+-- there's only one target triple per module, after all.+--+-- Hopefully, GHC is smart enough to construct these at compile-time.+newtype LookupTable a = LookupTable { getLookupTable :: [(String, a)] }++makeTable :: [(String, a)] -> LookupTable a+makeTable = LookupTable++enumTable :: Bounded a => Enum a => (a -> String) -> LookupTable a+enumTable prnt = makeTable [(prnt a, a) | a <- enumFrom minBound]++enumTableVariants :: Bounded a => Enum a => (a -> [String]) -> LookupTable a+enumTableVariants prnt =+ makeTable (concatMap (\a -> map (,a) (prnt a)) (enumFrom minBound))++--------------------------------------------------------------------------------+-- Queries++lookupBy :: (String -> Bool) -> LookupTable a -> Maybe a+lookupBy p = Maybe.listToMaybe . map snd . filter (p . fst) . getLookupTable++lookup :: String -> LookupTable a -> Maybe a+lookup s = lookupBy (== s)++lookupByPrefix :: String -> LookupTable a -> Maybe a+lookupByPrefix pfx = lookupBy (pfx `List.isPrefixOf`)++lookupByWithDefault :: a -> (String -> Bool) -> LookupTable a -> a+lookupByWithDefault def p = Maybe.fromMaybe def . lookupBy p++lookupWithDefault :: LookupTable a -> a -> String -> a+lookupWithDefault table def val = lookupByWithDefault def (== val) table++lookupByPrefixWithDefault :: LookupTable a -> a -> String -> a+lookupByPrefixWithDefault table def pfx =+ lookupByWithDefault def (pfx `List.isPrefixOf`) table++lookupBySuffixWithDefault :: LookupTable a -> a -> String -> a+lookupBySuffixWithDefault table def sfx =+ lookupByWithDefault def (sfx `List.isSuffixOf`) table
+ src/Text/LLVM/Triple/Print.hs view
@@ -0,0 +1,229 @@+{- |+Module : Text.LLVM.Triple.Print+Description : Printing of LLVM target triples.+License : BSD3+Maintainer : Langston Barrett+Stability : experimental+-}++{-# LANGUAGE LambdaCase #-}++module Text.LLVM.Triple.Print+ ( archName+ , vendorName+ , osName+ , envName+ , objFmtName+ , printTriple+ ) where++import qualified Data.List as List++import Text.LLVM.Triple.AST++-- | @llvm::Triple::getArchTypeName@.+--+-- Retained in the order in which they appear in the LLVM source, rather than an+-- order consistent with the constructors of 'Arch'.+archName :: Arch -> String+archName =+ \case+ UnknownArch -> "unknown"+ AArch64 -> "aarch64"+ AArch64_32 -> "aarch64_32"+ AArch64_BE -> "aarch64_be"+ AMDGCN -> "amdgcn"+ AMDIL64 -> "amdil64"+ AMDIL -> "amdil"+ ARC -> "arc"+ ARM -> "arm"+ ARMEB -> "armeb"+ AVR -> "avr"+ BPFEB -> "bpfeb"+ BPFEL -> "bpfel"+ CSKY -> "csky"+ DXIL -> "dxil"+ Hexagon -> "hexagon"+ HSAIL64 -> "hsail64"+ HSAIL -> "hsail"+ Kalimba -> "kalimba"+ Lanai -> "lanai"+ Le32 -> "le32"+ Le64 -> "le64"+ LoongArch32 -> "loongarch32"+ LoongArch64 -> "loongarch64"+ M68k -> "m68k"+ MIPS64 -> "mips64"+ MIPS64EL -> "mips64el"+ MIPS -> "mips"+ MIPSEL -> "mipsel"+ MSP430 -> "msp430"+ NVPTX64 -> "nvptx64"+ NVPTX -> "nvptx"+ PPC64 -> "powerpc64"+ PPC64LE -> "powerpc64le"+ PPC -> "powerpc"+ PPCLE -> "powerpcle"+ R600 -> "r600"+ RenderScript32 -> "renderscript32"+ RenderScript64 -> "renderscript64"+ RISCV32 -> "riscv32"+ RISCV64 -> "riscv64"+ SHAVE -> "shave"+ Sparc -> "sparc"+ SparcEL -> "sparcel"+ Sparcv9 -> "sparcv9"+ SPIR64 -> "spir64"+ SPIR -> "spir"+ SPIRV32 -> "spirv32"+ SPIRV64 -> "spirv64"+ SystemZ -> "s390x"+ TCE -> "tce"+ TCELE -> "tcele"+ Thumb -> "thumb"+ ThumbEB -> "thumbeb"+ VE -> "ve"+ Wasm32 -> "wasm32"+ Wasm64 -> "wasm64"+ X86 -> "i386"+ X86_64 -> "x86_64"+ XCore -> "xcore"++-- | @llvm::Triple::getVendorTypeName@.+--+-- Retained in the order in which they appear in the LLVM source.+vendorName :: Vendor -> String+vendorName =+ \case+ UnknownVendor -> "unknown"+ AMD -> "amd"+ Apple -> "apple"+ CSR -> "csr"+ Freescale -> "fsl"+ IBM -> "ibm"+ ImaginationTechnologies -> "img"+ Mesa -> "mesa"+ MipsTechnologies -> "mti"+ Myriad -> "myriad"+ NVIDIA -> "nvidia"+ OpenEmbedded -> "oe"+ PC -> "pc"+ SCEI -> "scei"+ SUSE -> "suse"++-- | @llvm::Triple::getOSTypeName@.+--+-- Retained in the order in which they appear in the LLVM source.+osName :: OS -> String+osName =+ \case+ UnknownOS -> "unknown"+ AIX -> "aix"+ AMDHSA -> "amdhsa"+ AMDPAL -> "amdpal"+ Ananas -> "ananas"+ CUDA -> "cuda"+ CloudABI -> "cloudabi"+ Contiki -> "contiki"+ Darwin -> "darwin"+ DragonFly -> "dragonfly"+ DriverKit -> "driverkit"+ ELFIAMCU -> "elfiamcu"+ Emscripten -> "emscripten"+ FreeBSD -> "freebsd"+ Fuchsia -> "fuchsia"+ Haiku -> "haiku"+ HermitCore -> "hermit"+ Hurd -> "hurd"+ IOS -> "ios"+ KFreeBSD -> "kfreebsd"+ Linux -> "linux"+ Lv2 -> "lv2"+ MacOSX -> "macosx"+ Mesa3D -> "mesa3d"+ Minix -> "minix"+ NVCL -> "nvcl"+ NaCl -> "nacl"+ NetBSD -> "netbsd"+ OpenBSD -> "openbsd"+ PS4 -> "ps4"+ PS5 -> "ps5"+ RTEMS -> "rtems"+ Solaris -> "solaris"+ TvOS -> "tvos"+ WASI -> "wasi"+ WatchOS -> "watchos"+ Win32 -> "windows"+ ZOS -> "zos"+ ShaderModel -> "shadermodel"++-- | @llvm::Triple::getEnvironmentName@.+--+-- Retained in the order in which they appear in the LLVM source.+envName :: Environment -> String+envName =+ \case+ UnknownEnvironment -> "unknown"+ Android -> "android"+ CODE16 -> "code16"+ CoreCLR -> "coreclr"+ Cygnus -> "cygnus"+ EABI -> "eabi"+ EABIHF -> "eabihf"+ GNU -> "gnu"+ GNUABI64 -> "gnuabi64"+ GNUABIN32 -> "gnuabin32"+ GNUEABI -> "gnueabi"+ GNUEABIHF -> "gnueabihf"+ GNUX32 -> "gnux32"+ GNUILP32 -> "gnu_ilp32"+ Itanium -> "itanium"+ MSVC -> "msvc"+ MacABI -> "macabi"+ Musl -> "musl"+ MuslEABI -> "musleabi"+ MuslEABIHF -> "musleabihf"+ MuslX32 -> "muslx32"+ Simulator -> "simulator"+ Pixel -> "pixel"+ Vertex -> "vertex"+ Geometry -> "geometry"+ Hull -> "hull"+ Domain -> "domain"+ Compute -> "compute"+ Library -> "library"+ RayGeneration -> "raygeneration"+ Intersection -> "intersection"+ AnyHit -> "anyhit"+ ClosestHit -> "closesthit"+ Miss -> "miss"+ Callable -> "callable"+ Mesh -> "mesh"+ Amplification -> "amplification"++-- | @llvm::Triple::getObjectFormatTypeName@+--+-- Retained in the order in which they appear in the LLVM source.+objFmtName :: ObjectFormat -> String+objFmtName =+ \case+ UnknownObjectFormat -> "" -- NB: Not "unknown"+ COFF -> "coff"+ ELF -> "elf"+ GOFF -> "goff"+ MachO -> "macho"+ Wasm -> "wasm"+ XCOFF -> "xcoff"+ DXContainer -> "dxcontainer"+ SPIRV -> "spirv"++printTriple :: TargetTriple -> String+printTriple tt =+ List.intercalate+ "-"+ [ archName (ttArch tt)+ , vendorName (ttVendor tt)+ , osName (ttOS tt)+ , envName (ttEnv tt)+ , objFmtName (ttObjFmt tt)+ ]
+ test/Main.hs view
@@ -0,0 +1,13 @@+module Main (main) where++import qualified Test.Tasty as Tasty++import qualified Triple+import qualified Output++main :: IO ()+main = Tasty.defaultMain $ Tasty.testGroup "LLVM tests"+ [+ Output.tests+ , Triple.tests+ ]
+ test/Output.hs view
@@ -0,0 +1,302 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE QuasiQuotes #-}++-- | This module provides some simple pretty-printing output verification tests.+-- This amounts to spot-checking a few places in the pretty printing that are+-- examined by hand: in general, it its much more effective to do round-trip+-- testing using AST's parsed from bitcode generated by actual programs, which is+-- what occurs in the llvm-pretty-bc-parser package (i.e. much more comprehensive+-- testing is deferred to the llvm-pretty-bc-parser package, which might then+-- reveal issues that need to be fixed in this llvm-pretty package).++module Output ( tests ) where++import Control.Monad ( unless )+import qualified Data.Text as T+import qualified Test.Tasty as Tasty+import Test.Tasty.HUnit+import qualified Text.PrettyPrint as PP++import Text.LLVM.AST+import Text.LLVM.PP++import TQQDefs++tests :: Tasty.TestTree+tests = Tasty.testGroup "LLVM pretty-printing output tests"+ $ let -- s1 is a non-sensical construct whose primary intention is to hold two+ -- sub-structures that change their pretty representations at different+ -- LLVM versions. The pretty output will be checked at different LLVM+ -- versions to ensure that the desired version-specific changes in the+ -- output are seen.+ s1, s2 :: Stmt+ s1 = Effect+ (GEP True (Alias (Ident "hi")) (Typed Opaque dcu) [])+ []+ s2 = Effect (Load PtrOpaque (Typed Opaque ValNull) Nothing Nothing)+ [ ("location", ValMdLoc $ DebugLoc { dlLine = 12+ , dlCol = 34+ , dlScope = ValMdRef 5+ , dlIA = Nothing+ , dlImplicit = True })+ ]+ dcu :: Value+ dcu = ValMd+ $ ValMdDebugInfo+ $ DebugInfoCompileUnit+ $ DICompileUnit { dicuLanguage = 12+ , dicuFile = Nothing+ , dicuProducer = Just "llvm-pretty-test"+ , dicuIsOptimized = True+ , dicuFlags = Just "some flags"+ , dicuRuntimeVersion = 3+ , dicuSplitDebugFilename = Nothing+ , dicuEmissionKind = 1+ , dicuEnums = Just dtt+ , dicuRetainedTypes = Nothing+ , dicuSubprograms = Nothing+ , dicuGlobals = Nothing+ , dicuImports = Nothing+ , dicuMacros = Nothing+ , dicuDWOId = 2+ , dicuSplitDebugInlining = False+ , dicuDebugInfoForProf = True+ , dicuNameTableKind = 4+ , dicuRangesBaseAddress = True+ , dicuSysRoot = Just "the root"+ , dicuSDK = Just "SDK"+ }+ dtt = ValMdDebugInfo+ $ DebugInfoTemplateTypeParameter+ $ DITemplateTypeParameter { dittpName = Just "ttp"+ , dittpType = Nothing+ , dittpIsDefault = Just True+ }+ blk1 = BasicBlock { bbLabel = Just $ Named $ Ident "blk1"+ , bbStmts =+ [ Result (Ident "r1") (Comment "insanity follows...") []+ , Effect (Jump $ Named $ Ident "blk1") []+ , Result (Ident "oh no") RetVoid []+ , Effect (Br (Typed (PrimType Metadata) ValZeroInit) (Anon 3) (Named "oh no")) []+ ]+ }+ blk2 = BasicBlock { bbLabel = Just $ Anon 123+ , bbStmts = []+ }+ ppToText = T.pack+ -- render with a line-length of 30 to encourage wrapping on+ -- most list elements or arguments for consistent output to+ -- verify against any changes.+ . PP.renderStyle (PP.Style PP.PageMode 30 1.0)+ in+ [+ testCase "Stmt 1, LLVM 3.5" $+ assertEqLines [sq|+ ----+ getelementptr inbounds opaque !DICompileUnit(language: 12,+ producer: "llvm-pretty-test",+ isOptimized: true,+ flags: "some flags",+ runtimeVersion: 3,+ emissionKind: 1,+ enums: !DITemplateTypeParameter(name: ttp),+ dwoId: 2,+ splitDebugInlining: false,+ debugInfoForProfiling: true,+ nameTableKind: 4)+ ----+ |]+ (ppToText $ ppLLVM35 ppStmt s1)++ , testCase "Stmt 1, LLVM 3.7" $+ assertEqLines [sq|+ In LLVM 3.7, the GEP instruction output shows the additional type+ ----+ getelementptr inbounds %hi, opaque !DICompileUnit(language: 12,+ producer: "llvm-pretty-test",+ isOptimized: true,+ flags: "some flags",+ runtimeVersion: 3,+ emissionKind: 1,+ enums: !DITemplateTypeParameter(name: ttp),+ dwoId: 2,+ splitDebugInlining: false,+ debugInfoForProfiling: true,+ nameTableKind: 4)+ ----+ |]+ (ppToText $ ppLLVM37 ppStmt s1)++ , testCase "Stmt 1, LLVM 10" $+ assertEqLines (ppToText $ ppLLVM 10 $ ppStmt s1) [sq|+ No change from LLVM 3.7 through LLVM 10+ ----+ getelementptr inbounds %hi, opaque !DICompileUnit(language: 12,+ producer: "llvm-pretty-test",+ isOptimized: true,+ flags: "some flags",+ runtimeVersion: 3,+ emissionKind: 1,+ enums: !DITemplateTypeParameter(name: ttp),+ dwoId: 2,+ splitDebugInlining: false,+ debugInfoForProfiling: true,+ nameTableKind: 4)+ ----+ |]++ , testCase "Stmt 1, LLVM 11" $+ assertEqLines (ppToText $ ppLLVM 11 $ ppStmt s1) [sq|+ In LLVM 11, DICompileUnit adds rangesBaseAddress, sysroot, and sdk+ ----+ getelementptr inbounds %hi, opaque !DICompileUnit(language: 12,+ producer: "llvm-pretty-test",+ isOptimized: true,+ flags: "some flags",+ runtimeVersion: 3,+ emissionKind: 1,+ enums: !DITemplateTypeParameter(name: ttp),+ dwoId: 2,+ splitDebugInlining: false,+ debugInfoForProfiling: true,+ nameTableKind: 4,+ rangesBaseAddress: true,+ sysroot: "the root",+ sdk: "SDK")+ ----+ |]++ ------------------------------------------------------------++ , testCase "Stmt 2, LLVM 3.5" $+ assertEqLines [sq|+ ----+ load opaque null, !location !MDLocation(line: 12,+ column: 34,+ scope: !5, implicit)+ ----+ |]+ (ppToText $ ppLLVM35 ppStmt s2)++ , testCase "Stmt 2, LLVM 3.7" $+ assertEqLines [sq|+ Beginning in LLVM 3.7, the type is no longer implicit and is explicitly+ shown, and the DebugLoc metadata is DILocation instead of MDLocation+ ----+ load ptr, opaque null, !location !DILocation(line: 12,+ column: 34,+ scope: !5, implicit)+ ----+ |]+ (ppToText $ ppLLVM37 ppStmt s2)++ , testCase "Stmt 2, LLVM 10" $+ assertEqLines [sq|+ No change since LLVM 3.7+ ----+ load ptr, opaque null, !location !DILocation(line: 12,+ column: 34,+ scope: !5, implicit)+ ----+ |]+ (ppToText $ ppLLVM 10 $ ppStmt s2)++ ------------------------------------------------------------+ -- Verify named labels and label targets are emitted correctly++ , testCase "Blk 1, LLVM 3.5" $+ assertEqLines (ppToText $ ppLLVM35 ppBasicBlock blk1) [sq|+ --------+ blk1:+ %r1 = ; insanity follows...+ br label %blk1+ %"oh no" = ret void+ br metadata zeroinitializer, label %3, label %"oh no"+ --------+ |]++ , testCase "Blk 1, LLVM 3.7" $+ assertEqLines (ppToText $ ppLLVM37 ppBasicBlock blk1) [sq|+ --------+ blk1:+ %r1 = ; insanity follows...+ br label %blk1+ %"oh no" = ret void+ br metadata zeroinitializer, label %3, label %"oh no"+ --------+ |]++ ------------------------------------------------------------+ -- Verify anonymous labels are emitted correctly++ , testCase "Blk 2, LLVM 3.5" $+ assertEqLines (ppToText $ ppLLVM35 ppBasicBlock blk2) [sq|+ --------+ ; <label>: 123+ --------+ |]++ , testCase "Blk 2, LLVM 3.7" $+ assertEqLines (ppToText $ ppLLVM37 ppBasicBlock blk2) [sq|+ --------+ ; <label>: 123+ --------+ |]++ ]++----------------------------------------------------------------------++assertEqLines :: T.Text -> T.Text -> IO ()+assertEqLines t1 t2 =+ unless (t1 == t2) $ assertFailure $ multiLineDiff t1 t2++-- | The multiLineDiff is another helper function that can be used to+-- format a line-by-line difference display of two Text+-- representations. This is provided as a convenience function to+-- help format large text regions for easier comparison.++multiLineDiff :: T.Text -> T.Text -> String+multiLineDiff expected actual =+ let dl (e,a) = if e == a then db e else de " ↱" e <> "\n " <> da " ↳" a+ db b = "| > " <> b+ de m e = "|" <> m <> "expect> " <> e+ da m a = "|" <> m <> "actual> " <> a+ el = take 1450 (visible <$> T.lines expected)+ al = take 1450 (visible <$> T.lines actual)+ visible = T.replace " " "␠"+ . T.replace "\n" ""+ . T.replace "\t" "␉"+ . T.replace "\012" "␍"+ addnum :: Int -> T.Text -> T.Text+ addnum n l = let nt = T.pack (show n)+ nl = T.length nt+ in T.take (4 - nl) " " <> nt <> l+ ll = T.pack . show . length+ tl = T.pack . show . T.length+ banner = "MISMATCH between "+ <> ll el <> "l/" <> tl expected <> "c expected and "+ <> ll al <> "l/" <> tl actual <> "c actual"+ diffReport = fmap (uncurry addnum) $+ zip [1..] $ concat $+ -- Highly simplistic "diff" output assumes+ -- correlated lines: added or removed lines just+ -- cause everything to shown as different from that+ -- point forward.+ [ fmap dl $ zip el al+ , fmap (de "∌ ") $ drop (length al) el+ , fmap (da "∹ ") $ drop (length el) al+ ]+ -- n.b. T.lines seems to consume trailing whitespace before+ -- newlines as well. This will show any of this whitespace+ -- difference on the last line, but not for other lines with+ -- whitespace.+ <> if el == al+ then let maxlen = max (T.length expected) (T.length actual)+ end x = T.drop (maxlen - 5) x+ in [ [ de "∌ ending " $ visible $ end expected ]+ , [ da "∹ ending " $ visible $ end actual ]+ ]+ else mempty+ details = banner : diffReport+ in if expected == actual then "<no difference>" else T.unpack (T.unlines details)
+ test/TQQDefs.hs view
@@ -0,0 +1,62 @@+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TemplateHaskell #-}++module TQQDefs where++import Data.String+import Language.Haskell.TH ( ExpQ )+import Language.Haskell.TH.Quote+import Numeric.Natural+++sq :: QuasiQuoter+sq = QuasiQuoter extractor+ (error "no q patterns")+ (error "no q types")+ (error "no q dec")++extractor :: String -> ExpQ+extractor s =+ case inSeps $ filter (/= '\r') s of+ Post a -> [|fromString a|]+ Pre _ -> error $ "No starting line found"+ MatchLine _ -> error $ "Only starting line found"+ Pass _ _ _ -> error $ "No ending line found"+++data QState = Pre String+ | MatchLine Natural+ | Pass Natural Natural String+ | Post String++inSeps :: String -> QState+inSeps =+ let sep = "----"+ sepl = length sep+ matchSep s = if take sepl s == reverse sep+ then let ss n = \case+ [] -> Nothing+ ('\n':_) -> Just n+ (' ':cs) -> ss (n+1) cs+ _ -> Nothing+ in ss 0 $ drop sepl s+ else Nothing+ nxtC :: QState -> Char -> QState+ nxtC = \case+ (Post s) -> const $ Post s+ (Pre p) -> \c -> let p' = c : p+ in case matchSep p' of+ Just n -> MatchLine n+ Nothing -> Pre p'+ (MatchLine n) -> \c -> if '\n' == c then Pass n n "" else MatchLine n+ (Pass n p s) -> \c ->+ let s' = c : s+ in if p == 0+ then if c == '\n' && n > 0+ then Pass n n s'+ else if take sepl s' == reverse sep+ then Post $ reverse $ drop (sepl + 1) s'+ else Pass n 0 s'+ else Pass n (p-1) s+ in foldl nxtC (Pre "")
+ test/Triple.hs view
@@ -0,0 +1,72 @@+module Triple (tests) where++import Control.Monad (forM_)++import qualified Text.LLVM.Triple.AST as AST+import qualified Text.LLVM.Triple.Parse as Parse+import qualified Text.LLVM.Triple.Print as Print++import qualified Test.Tasty as Tasty+import qualified Test.Tasty.HUnit as TastyH++each :: Bounded a => Enum a => (a -> String) -> (a -> Bool) -> IO ()+each name test =+ forM_ (enumFrom minBound) $ \e ->+ TastyH.assertBool (name e) (test e)++tests :: Tasty.TestTree+tests =+ Tasty.testGroup+ "Triple parse/print"+ [ TastyH.testCase+ "parse . print == id :: Arch -> Arch"+ (roundtrip Parse.parseArch Print.archName)+ , TastyH.testCase+ "parse . print == id :: Vendor -> Vendor"+ (roundtrip Parse.parseVendor Print.vendorName)+ , TastyH.testCase+ "parse . print == id :: OS -> OS"+ (roundtrip Parse.parseOS Print.osName)+ , TastyH.testCase+ "parse . print == id :: Environment -> Environment"+ (roundtrip Parse.parseEnv Print.envName)+ , TastyH.testCase+ "parse . print == id :: ObjectFormat -> ObjectFormat"+ (roundtrip Parse.parseObjFmt Print.objFmtName)+ , triple "aarch64-unknown-linux-gnu" $+ AST.TargetTriple+ { AST.ttArch = AST.AArch64+ , AST.ttSubArch = AST.NoSubArch+ , AST.ttVendor = AST.UnknownVendor+ , AST.ttOS = AST.Linux+ , AST.ttEnv = AST.GNU+ , AST.ttObjFmt = AST.UnknownObjectFormat+ }+ , triple "x86_64-unknown-linux-gnu" $+ AST.TargetTriple+ { AST.ttArch = AST.X86_64+ , AST.ttSubArch = AST.NoSubArch+ , AST.ttVendor = AST.UnknownVendor+ , AST.ttOS = AST.Linux+ , AST.ttEnv = AST.GNU+ , AST.ttObjFmt = AST.UnknownObjectFormat+ }+ , triple "i386-unknown-linux-elf" $+ AST.TargetTriple+ { AST.ttArch = AST.X86+ , AST.ttSubArch = AST.NoSubArch+ , AST.ttVendor = AST.UnknownVendor+ , AST.ttOS = AST.Linux+ , AST.ttEnv = AST.UnknownEnvironment+ , AST.ttObjFmt = AST.ELF+ }+ ]+ where+ triple s t =+ TastyH.testCase+ ("parse '" ++ s ++ "'")+ (t TastyH.@=? Parse.parseTriple s)+ roundtrip pars prnt =+ each+ (\a -> "parse (print " ++ prnt a ++ ") == " ++ prnt a)+ (\a -> a == pars (prnt a))