packages feed

llvm-hs-pretty 0.4.0.0 → 0.5.0.0

raw patch · 3 files changed

+1337/−1281 lines, 3 filesdep +prettyprinterdep −wl-pprint-textPVP ok

version bump matches the API change (PVP)

Dependencies added: prettyprinter

Dependencies removed: wl-pprint-text

API changes (from Hackage documentation)

- LLVM.Pretty: class PP p
- LLVM.Pretty: instance LLVM.Pretty.PP (Data.Either.Either LLVM.AST.FunctionAttribute.GroupID LLVM.AST.FunctionAttribute.FunctionAttribute)
- LLVM.Pretty: instance LLVM.Pretty.PP (LLVM.AST.Operand.Operand, [LLVM.AST.ParameterAttribute.ParameterAttribute])
- LLVM.Pretty: instance LLVM.Pretty.PP ([LLVM.AST.Global.Parameter], GHC.Types.Bool)
- LLVM.Pretty: instance LLVM.Pretty.PP Data.ByteString.Short.Internal.ShortByteString
- LLVM.Pretty: instance LLVM.Pretty.PP GHC.Int.Int32
- LLVM.Pretty: instance LLVM.Pretty.PP GHC.Int.Int64
- LLVM.Pretty: instance LLVM.Pretty.PP GHC.Integer.Type.Integer
- LLVM.Pretty: instance LLVM.Pretty.PP GHC.Types.Bool
- LLVM.Pretty: instance LLVM.Pretty.PP GHC.Word.Word16
- LLVM.Pretty: instance LLVM.Pretty.PP GHC.Word.Word32
- LLVM.Pretty: instance LLVM.Pretty.PP GHC.Word.Word64
- LLVM.Pretty: instance LLVM.Pretty.PP GHC.Word.Word8
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.COMDAT.SelectionKind
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.CallingConvention.CallingConvention
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Constant.Constant
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.DataLayout.DataLayout
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Definition
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.FloatingPointPredicate.FloatingPointPredicate
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.FunctionAttribute.FunctionAttribute
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.FunctionAttribute.GroupID
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Global.BasicBlock
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Global.Global
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Global.Parameter
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Global.UnnamedAddr
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Instruction.Atomicity
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Instruction.Instruction
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Instruction.InstructionMetadata
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Instruction.LandingPadClause
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Instruction.MemoryOrdering
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Instruction.SynchronizationScope
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Instruction.Terminator
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.IntegerPredicate.IntegerPredicate
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Linkage.Linkage
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Module
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Name.Name
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.BasicTypeTag
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.CallableOperand
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.ChecksumKind
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.DIBasicType
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.DICompileUnit
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.DICompositeType
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.DIDerivedType
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.DIEnumerator
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.DIExpression
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.DIFile
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.DIFlag
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.DIGlobalVariable
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.DIGlobalVariableExpression
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.DIImportedEntity
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.DILexicalBlockBase
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.DILocalScope
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.DILocalVariable
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.DILocation
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.DIMacroInfo
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.DIMacroNode
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.DIModule
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.DINamespace
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.DINode
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.DIObjCProperty
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.DIScope
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.DISubprogram
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.DISubrange
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.DISubroutineType
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.DITemplateParameter
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.DIType
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.DIVariable
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.DebugEmissionKind
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.DerivedTypeTag
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.Encoding
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.ImportedEntityTag
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.MDNode
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.Metadata
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.MetadataNodeID
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Operand.Operand
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.ParameterAttribute.ParameterAttribute
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.RMWOperation.RMWOperation
- LLVM.Pretty: instance LLVM.Pretty.PP LLVM.AST.Type.Type
- LLVM.Pretty: instance LLVM.Pretty.PP [Data.Either.Either LLVM.AST.FunctionAttribute.GroupID LLVM.AST.FunctionAttribute.FunctionAttribute]
- LLVM.Pretty: instance LLVM.Pretty.PP [GHC.Types.Char]
- LLVM.Pretty: instance LLVM.Pretty.PP [LLVM.AST.ParameterAttribute.ParameterAttribute]
- LLVM.Pretty: instance LLVM.Pretty.PP a => LLVM.Pretty.PP (LLVM.AST.Instruction.Named a)
- LLVM.Pretty: instance LLVM.Pretty.PP a => LLVM.Pretty.PP (LLVM.AST.Operand.MDRef a)
- LLVM.Pretty: pp :: PP p => p -> Doc
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty (Data.Either.Either LLVM.AST.FunctionAttribute.GroupID LLVM.AST.FunctionAttribute.FunctionAttribute)
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty Data.ByteString.Short.Internal.ShortByteString
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.COMDAT.SelectionKind
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.CallingConvention.CallingConvention
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Constant.Constant
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.DataLayout.DataLayout
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Definition
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.FloatingPointPredicate.FloatingPointPredicate
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.FunctionAttribute.FunctionAttribute
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.FunctionAttribute.GroupID
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Global.BasicBlock
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Global.Global
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Global.Parameter
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Global.UnnamedAddr
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Instruction.Instruction
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Instruction.LandingPadClause
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Instruction.MemoryOrdering
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Instruction.SynchronizationScope
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Instruction.Terminator
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.IntegerPredicate.IntegerPredicate
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Linkage.Linkage
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Module
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Name.Name
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.BasicTypeTag
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.CallableOperand
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.ChecksumKind
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.DIBasicType
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.DICompileUnit
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.DICompositeType
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.DIDerivedType
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.DIEnumerator
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.DIExpression
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.DIFile
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.DIFlag
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.DIGlobalVariable
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.DIGlobalVariableExpression
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.DIImportedEntity
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.DILexicalBlockBase
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.DILocalScope
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.DILocalVariable
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.DILocation
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.DIMacroInfo
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.DIMacroNode
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.DIModule
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.DINamespace
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.DINode
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.DIObjCProperty
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.DIScope
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.DISubprogram
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.DISubrange
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.DISubroutineType
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.DITemplateParameter
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.DIType
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.DIVariable
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.DebugEmissionKind
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.DerivedTypeTag
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.Encoding
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.ImportedEntityTag
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.MDNode
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.Metadata
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.MetadataNodeID
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Operand.Operand
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.ParameterAttribute.ParameterAttribute
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.RMWOperation.RMWOperation
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty LLVM.AST.Type.Type
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty a => Data.Text.Prettyprint.Doc.Internal.Pretty (LLVM.AST.Instruction.Named a)
+ LLVM.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty a => Data.Text.Prettyprint.Doc.Internal.Pretty (LLVM.AST.Operand.MDRef a)
- LLVM.Pretty: ppll :: PP a => a -> Text
+ LLVM.Pretty: ppll :: Pretty a => a -> Text

Files

ChangeLog.md view
@@ -1,5 +1,13 @@ # Revision history for llvm-hs-typed +## 0.4++* Added support for inline assembly++## 0.3++* Update for llvm-hs 6.2.+ ## 0.2  * Added support for DataLayout pretty printing.
llvm-hs-pretty.cabal view
@@ -1,5 +1,5 @@ name:                llvm-hs-pretty-version:             0.4.0.0+version:             0.5.0.0 license:             MIT synopsis:            A pretty printer for LLVM IR.  description:         A pretty printer for the LLVM AST types provided by llvm-hs.@@ -31,7 +31,7 @@     bytestring           >= 0.10,     llvm-hs-pure         >= 6.2,     text                 >= 0.1,-    wl-pprint-text       >= 1.1+    prettyprinter        >= 1.2  Test-suite test   type:                exitcode-stdio-1.0
src/LLVM/Pretty.hs view
@@ -10,1282 +10,1330 @@ {-# OPTIONS_GHC -fwarn-incomplete-uni-patterns #-}  module LLVM.Pretty (-  PP(..),-  ppllvm,-  ppll,-) where--import Prelude hiding ((<$>))-import GHC.Word--import LLVM.AST.Typed--import LLVM.AST-import LLVM.AST.Global-import LLVM.AST.Type--import LLVM.DataLayout-import LLVM.AST.Attribute-import LLVM.AST.DataLayout-import LLVM.AST.COMDAT-import qualified LLVM.AST.Linkage as L-import qualified LLVM.AST.Visibility as V-import qualified LLVM.AST.CallingConvention as CC-import qualified LLVM.AST.Constant as C-import qualified LLVM.AST.FloatingPointPredicate as FP-import qualified LLVM.AST.IntegerPredicate as IP-import qualified LLVM.AST.InlineAssembly as IA-import qualified LLVM.AST.AddrSpace as AS-import qualified LLVM.AST.Float as F-import qualified LLVM.AST.RMWOperation as RMW-import LLVM.AST.Operand hiding (DIGLobalVariable(..), GlobalVariable, Module, NoReturn, PointerType)-import qualified LLVM.AST.Operand as O-import LLVM.AST.ParameterAttribute as PA-import LLVM.AST.FunctionAttribute as FA--import Data.String--import Text.Printf-import Data.Text.Lazy.Encoding-import Data.Text.Lazy (Text, pack, unpack)-import qualified Data.ByteString.Short as SBF-import qualified Data.ByteString.Lazy.Char8 as BF-import Data.ByteString.Lazy (fromStrict)-import Data.ByteString.Internal (w2c)-import Text.PrettyPrint.Leijen.Text hiding (column, line, (<>))--import qualified Data.ByteString.Char8 as BL-import qualified Data.ByteString.Short as BS-import Data.Char (chr, ord, isAscii, isControl, isLetter, isDigit)-import Data.Foldable (toList)-import Data.Int-import Data.List (intersperse)-import Data.Maybe (isJust, mapMaybe)-import Data.Monoid ((<>))-import Numeric (showHex)--import Data.Array.Unsafe-import Data.Array.MArray-import Data.Array.ST-import Control.Monad.ST------------------------------------------------------------------------------------ Utils----------------------------------------------------------------------------------parensIf ::  Bool -> Doc -> Doc-parensIf True = parens-parensIf False = id--commas :: [Doc] -> Doc-commas  = hsep . punctuate (char ',')--colons :: [Doc] -> Doc-colons  = hcat . intersperse (char ':')--hlinecat :: [Doc] -> Doc-hlinecat = vcat . intersperse softbreak--wrapbraces :: Doc -> Doc -> Doc-wrapbraces leadIn x = (leadIn <> char '{') <$> x <$> char '}'--angleBrackets :: Doc -> Doc-angleBrackets x = char '<' <> x <> char '>'--spacedbraces :: Doc -> Doc-spacedbraces x = char '{' <+> x <+> char '}'--local' :: Doc -> Doc-local' a = "%" <> a--global :: Doc -> Doc-global a = "@" <> a--label :: Doc -> Doc-label a = "label" <+> "%" <> a--cma :: Doc -> Doc -> Doc -- <,> does not work :(-a `cma` b = a <> "," <+> b------------------------------------------------------------------------------------ Classes----------------------------------------------------------------------------------class PP p where-  pp :: p -> Doc--ppMaybe :: PP a => Maybe a -> Doc-ppMaybe (Just x) = pp x-ppMaybe Nothing = empty--ppBool :: Doc -> Bool -> Doc-ppBool x True = x-ppBool x False = empty---- XXX: horrible hack-unShort :: BS.ShortByteString -> [Char]-unShort xs = fmap (toEnum . fromIntegral) $ BS.unpack xs--short :: BS.ShortByteString -> Doc-short x = string (pack (unShort x))--decodeShortUtf8 :: SBF.ShortByteString -> Text-decodeShortUtf8 = decodeUtf8 . fromStrict . SBF.fromShort--instance PP Word8 where-  pp x = int (fromIntegral x)--instance PP Word16 where-  pp x = int (fromIntegral x)--instance PP Word32 where-  pp x = int (fromIntegral x)--instance PP Word64 where-  pp x = int (fromIntegral x)--instance PP Int32 where-  pp x = int (fromIntegral x)--instance PP Int64 where-  pp x = int (fromIntegral x)--instance PP Integer where-  pp = integer--instance PP BS.ShortByteString where-  pp = pp . unShort--instance PP [Char] where-  pp = text . pack--instance PP Bool where-  pp True = "true"-  pp False = "false"--instance PP Name where-  pp (Name nm)-   | BS.null nm = dquotes empty-    | isFirst first && all isRest name = text (pack name)-    | otherwise = dquotes . hcat . map escape $ name-    where-        name = unShort nm-        first = head name-        isFirst c = isLetter c || c == '-' || c == '_' || c == '$' || c == '.'-        isRest c = isDigit c || isFirst c-  pp (UnName x) = int (fromIntegral x)--instance PP Parameter where-  pp (Parameter ty (UnName _) attrs) = pp ty <+> pp attrs-  pp (Parameter ty name attrs) = pp ty <+> pp attrs <+> local' (pp name)--instance PP [ParameterAttribute] where-  pp x = hsep $ fmap pp x--instance PP ([Parameter], Bool) where-  pp (params, False) = commas (fmap pp params)-  pp (params, True) = "TODO" -- XXX: variadic case--instance PP (Operand, [ParameterAttribute]) where-  pp (op, attrs) = pp (typeOf op) <+> pp attrs <+> pp op--instance PP UnnamedAddr where-  pp LocalAddr = "local_unnamed_addr"-  pp GlobalAddr = "unnamed_addr"--instance PP Type where-  pp (IntegerType width) = "i" <> pp width-  pp (FloatingPointType HalfFP)      = "half"-  pp (FloatingPointType FloatFP )    = "float"-  pp (FloatingPointType DoubleFP)    = "double"-  pp (FloatingPointType FP128FP)     = "fp128"-  pp (FloatingPointType X86_FP80FP)  = "x86_fp80"-  pp (FloatingPointType PPC_FP128FP) = "ppc_fp128"--  pp VoidType = "void"-  pp (PointerType ref (AS.AddrSpace addr))-    | addr == 0 = pp ref <> "*"-    | otherwise = pp ref <+> "addrspace" <> parens (pp addr) <> "*"-  pp ft@(FunctionType {..}) = pp resultType <+> ppFunctionArgumentTypes ft-  pp (VectorType {..}) = "<" <> pp nVectorElements <+> "x" <+> pp elementType <> ">"-  pp (StructureType {..}) = if isPacked-                               then "<{" <> (commas $ fmap pp elementTypes ) <> "}>"-                               else  "{" <> (commas $ fmap pp elementTypes ) <> "}"-  pp (ArrayType {..}) = brackets $ pp nArrayElements <+> "x" <+> pp elementType-  pp (NamedTypeReference name) = "%" <> pp name-  pp MetadataType = "metadata"-  pp TokenType = "token"-  pp LabelType = "label"--instance PP Global where-  pp Function {..} =-      case basicBlocks of-        [] ->-          ("declare" <+> pp linkage <+> pp callingConvention-            <+> pp returnAttributes <+> pp returnType <+> global (pp name)-            <> ppParams (pp . typeOf) parameters <+> pp functionAttributes <+> align <+> gcName <+> pre)--        -- single unnamed block is special cased, and won't parse otherwise... yeah good times-        [b@(BasicBlock (UnName _) _ _)] ->-            ("define" <+> pp linkage <+> pp callingConvention-              <+> pp returnAttributes <+> pp returnType <+> global (pp name)-              <> ppParams pp parameters <+> pp functionAttributes <+> align <+> gcName <+> pre)-            `wrapbraces` (indent 2 $ ppSingleBlock b)--        bs ->-          ("define" <+> pp linkage <+> pp callingConvention-            <+> pp returnAttributes <+> pp returnType <+> global (pp name)-            <> ppParams pp parameters <+> pp functionAttributes <+> align <+> gcName <+> pre)-          `wrapbraces` (vcat $ fmap pp bs)-    where-      pre = case prefix of-              Nothing  -> empty-              Just con -> "prefix" <+> ppTyped con-      align | alignment == 0    = empty-            | otherwise = "align" <+> pp alignment-      gcName = maybe empty (\n -> "gc" <+> dquotes (text $ pack n)) (fmap unShort garbageCollectorName)--  pp GlobalVariable {..} = global (pp name) <+> "=" <+> ppLinkage hasInitializer linkage <+> ppMaybe unnamedAddr-                             <+> addrSpace' <+> kind <+> pp type' <+> ppMaybe initializer <> ppAlign alignment-    where-      hasInitializer = isJust initializer-      addrSpace' =-        case addrSpace of-          AS.AddrSpace addr-            | addr == 0 -> mempty-            | otherwise -> "addrspace" <> parens (pp addr)-      kind | isConstant = "constant"-           | otherwise  = "global"--  pp GlobalAlias {..} = global (pp name) <+> "=" <+> pp linkage <+> ppMaybe unnamedAddr <+> "alias" <+> pp typ `cma` ppTyped aliasee-    where-      typ = getElementType type'--ppMetadata :: Maybe Metadata -> Doc-ppMetadata Nothing = "null"-ppMetadata (Just m) = pp m--instance PP Definition where-  pp (GlobalDefinition x) = pp x-  pp (TypeDefinition nm ty) = local' (pp nm) <+> "=" <+> "type" <+> maybe "opaque" pp ty-  pp (FunctionAttributes gid attrs) = "attributes" <+> pp gid <+> "=" <+> braces (hsep (fmap ppAttrInGroup attrs))-  pp (NamedMetadataDefinition nm meta) = "!" <> short nm <+> "=" <+> "!" <> braces (commas (fmap pp meta))-  pp (MetadataNodeDefinition node meta) = pp node <+> "=" <+> pp meta-  pp (ModuleInlineAssembly asm) = "module asm" <+> dquotes (text (pack (BL.unpack asm)))-  pp (COMDAT name selKind) = "$" <> short name <+> "=" <+> "comdat" <+> pp selKind--instance PP SelectionKind where-  pp Any = "any"-  pp ExactMatch = "exactmatch"-  pp Largest = "largest"-  pp NoDuplicates = "noduplicates"-  pp SameSize = "samesize"--ppAttrInGroup :: FunctionAttribute -> Doc-ppAttrInGroup = \case-  StackAlignment n -> "alignstack=" <> pp n-  attr -> pp attr--instance PP FunctionAttribute where-  pp = \case-   NoReturn            -> "noreturn"-   NoUnwind            -> "nounwind"-   FA.ReadNone         -> "readnone"-   FA.ReadOnly         -> "readonly"-   FA.WriteOnly        -> "writeonly"-   NoInline            -> "noinline"-   AlwaysInline        -> "alwaysinline"-   MinimizeSize        -> "minsize"-   OptimizeForSize     -> "optsize"-   OptimizeNone        -> "optnone"-   SafeStack           -> "safestack"-   StackProtect        -> "ssp"-   StackProtectReq     -> "sspreq"-   StackProtectStrong  -> "sspstrong"-   NoRedZone           -> "noredzone"-   NoImplicitFloat     -> "noimplicitfloat"-   Naked               -> "naked"-   InlineHint          -> "inlinehint"-   StackAlignment n    -> "alignstack" <> parens (pp n)-   ReturnsTwice        -> "returns_twice"-   UWTable             -> "uwtable"-   NonLazyBind         -> "nonlazybind"-   Builtin             -> "builtin"-   NoBuiltin           -> "nobuiltin"-   Cold                -> "cold"-   JumpTable           -> "jumptable"-   NoDuplicate         -> "noduplicate"-   SanitizeAddress     -> "sanitize_address"-   SanitizeThread      -> "sanitize_thread"-   SanitizeMemory      -> "sanitize_memory"-   SanitizeHWAddress   -> "sanitize_hwaddress"-   NoRecurse           -> "norecurse"-   Convergent          -> "convergent"-   ArgMemOnly          -> "argmemonly"-   InaccessibleMemOnly -> "inaccessiblememonly"-   AllocSize a Nothing -> "allocsize" <> parens (pp a)-   AllocSize a (Just b) -> "allocsize" <> parens (commas [pp a, pp b])-   InaccessibleMemOrArgMemOnly -> "inaccessiblemem_or_argmemonly"-   FA.StringAttribute k v -> dquotes (short k) <> "=" <> dquotes (short v)-   Speculatable        -> "speculatable"-   StrictFP            -> "strictfp"--instance PP ParameterAttribute where-  pp = \case-    ZeroExt                    -> "zeroext"-    SignExt                    -> "signext"-    InReg                      -> "inreg"-    SRet                       -> "sret"-    Alignment word             -> "align" <+> pp word-    NoAlias                    -> "noalias"-    ByVal                      -> "byval"-    NoCapture                  -> "nocapture"-    Nest                       -> "nest"-    PA.ReadNone                -> "readnone"-    PA.ReadOnly                -> "readonly"-    PA.WriteOnly               -> "writeonly"-    InAlloca                   -> "inalloca"-    NonNull                    -> "nonnull"-    Dereferenceable word       -> "dereferenceable" <> parens (pp word)-    DereferenceableOrNull word -> "dereferenceable_or_null" <> parens (pp word)-    Returned                   -> "returned"-    SwiftSelf                  -> "swiftself"-    SwiftError                 -> "swifterror"-    PA.StringAttribute k v -> dquotes (short k) <> "=" <> dquotes (short v)--instance PP CC.CallingConvention where-  pp = \case-   CC.Numbered word -> "cc" <+> pp word-   CC.C             -> "ccc"-   CC.Fast          -> "fastcc"-   CC.Cold          -> "coldcc"-   CC.GHC           -> "cc 10"-   CC.HiPE          -> "cc 11"-   CC.WebKit_JS     -> "webkit_jscc"-   CC.AnyReg        -> "anyregcc"-   CC.PreserveMost  -> "preserve_mostcc"-   CC.PreserveAll   -> "preserve_allcc"-   CC.Swift         -> "swiftcc"-   CC.CXX_FastTLS   -> "cxx_fast_tlscc"-   CC.X86_StdCall   -> "cc 64"-   CC.X86_FastCall  -> "cc 65"-   CC.ARM_APCS      -> "cc 66"-   CC.ARM_AAPCS     -> "cc 67"-   CC.ARM_AAPCS_VFP -> "cc 68"-   CC.MSP430_INTR   -> "cc 69"-   CC.X86_ThisCall  -> "cc 70"-   CC.PTX_Kernel    -> "cc 71"-   CC.PTX_Device    -> "cc 72"-   CC.SPIR_FUNC     -> "cc 75"-   CC.SPIR_KERNEL   -> "cc 76"-   CC.Intel_OCL_BI  -> "cc 77"-   CC.X86_64_SysV   -> "cc 78"-   CC.Win64         -> "cc 79"-   CC.X86_Intr      -> "x86_intrcc"-   CC.X86_RegCall   -> "x86_regcallcc"-   CC.X86_VectorCall -> "x86_vectorcallcc"-   CC.AVR_Intr      -> "avr_intrcc"-   CC.AVR_Signal    -> "avr_signalcc"-   CC.AVR_Builtin   -> "cc 86"-   CC.HHVM          -> "hhvmcc"-   CC.HHVM_C        -> "hhvm_ccc"-   CC.AMDGPU_VS     -> "amdgpu_vs"-   CC.AMDGPU_GS     -> "amdgpu_gs"-   CC.AMDGPU_PS     -> "amdgpu_ps"-   CC.AMDGPU_CS     -> "amdgpu_cs"-   CC.AMDGPU_HS     -> "amdgpu_hs"-   CC.AMDGPU_Kernel -> "amdgpu_kernel"-   CC.MSP430_Builtin -> "msp430"--instance PP L.Linkage where-    pp = ppLinkage False--ppLinkage :: Bool -> L.Linkage -> Doc-ppLinkage omitExternal = \case-   L.External | omitExternal -> empty-              | otherwise    -> "external"-   L.Private                 -> "private"-   L.Internal                -> "internal"-   L.ExternWeak              -> "extern_weak"-   L.AvailableExternally     -> "available_externally"-   L.LinkOnce                -> "linkonce"-   L.Weak                    -> "weak"-   L.Common                  -> "common"-   L.Appending               -> "appending"-   L.LinkOnceODR             -> "linkonce_odr"-   L.WeakODR                 -> "weak_odr"--instance PP InstructionMetadata where-  pp meta = commas ["!" <> pp x <+> pp y | (x,y) <- meta]--instance PP MetadataNodeID where-  pp (MetadataNodeID x) = "!" <> int (fromIntegral x)--instance PP GroupID where-  pp (GroupID x) = "#" <> int (fromIntegral x)--instance PP BasicBlock where-  pp (BasicBlock nm instrs term) =-    label <$> indent 2 (vcat $ (fmap pp instrs) ++ [pp term])-    where-      label = case nm of-        UnName _ -> "; <label>:" <> pp nm <> ":"-        _ -> pp nm <> ":"--instance PP Terminator where-  pp = \case-    Br dest meta -> "br" <+> label (pp dest) <+> ppInstrMeta meta--    Ret val meta -> "ret" <+> maybe "void" ppTyped val <+> ppInstrMeta meta--    CondBr cond tdest fdest meta ->-     "br" <+> ppTyped cond-     `cma` label (pp tdest)-     `cma` label (pp fdest)-     <+> ppInstrMeta meta--    Switch {..} -> "switch" <+> ppTyped operand0'-                 `cma` label (pp defaultDest)-                 <+> brackets (hsep [ ppTyped v `cma` label (pp l) | (v,l) <- dests ])-                 <+> ppInstrMeta metadata'--    Unreachable {..} -> "unreachable" <+> ppInstrMeta metadata'--    IndirectBr op dests meta -> "indirectbr" <+> ppTyped op `cma`-     brackets (hsep [ label (pp l) | l <- dests ])-     <+> ppInstrMeta meta--    e @ Invoke {..} ->-     ppInvoke e-     <+> "to" <+> label (pp returnDest)-     <+> "unwind" <+> label (pp exceptionDest)-     <+> ppInstrMeta metadata'--    Resume op meta -> "resume "<+> ppTyped op <+> ppInstrMeta meta--    CleanupRet pad dest meta ->-      "cleanupret" <+> "from" <+> pp pad <+> "unwind" <+> maybe "to caller" (label . pp) dest-      <+> ppInstrMeta meta--    CatchRet catchPad succ meta ->-      "catchret" <+> "from" <+> pp catchPad <+> "to" <+> label (pp succ)-      <+> ppInstrMeta meta--    CatchSwitch {..} ->-      "catchswitch" <+> "within" <+> pp parentPad' <+>-      brackets (commas (map (label . pp) (toList catchHandlers))) <+>-      "unwind" <+> "to" <+> maybe "caller" pp defaultUnwindDest-      <+> ppInstrMeta metadata'--instance PP Instruction where-  pp = \case-    Add {..}    -> "add"  <+> ppTyped operand0 `cma` pp operand1 <+> ppInstrMeta metadata-    Sub {..}    -> "sub"  <+> ppTyped operand0 `cma` pp operand1 <+> ppInstrMeta metadata-    Mul {..}    -> "mul"  <+> ppTyped operand0 `cma` pp operand1 <+> ppInstrMeta metadata-    Shl {..}    -> "shl"  <+> ppTyped operand0 `cma` pp operand1 <+> ppInstrMeta metadata-    AShr {..}   -> "ashr" <+> ppTyped operand0 `cma` pp operand1 <+> ppInstrMeta metadata-    LShr {..}   -> "lshr" <+> ppTyped operand0 `cma` pp operand1 <+> ppInstrMeta metadata-    And {..}    -> "and"  <+> ppTyped operand0 `cma` pp operand1 <+> ppInstrMeta metadata-    Or {..}     -> "or"   <+> ppTyped operand0 `cma` pp operand1 <+> ppInstrMeta metadata-    Xor {..}    -> "xor"  <+> ppTyped operand0 `cma` pp operand1 <+> ppInstrMeta metadata-    SDiv {..}   -> "sdiv"  <+> ppTyped operand0 `cma` pp operand1 <+> ppInstrMeta metadata-    UDiv {..}   -> "udiv"  <+> ppTyped operand0 `cma` pp operand1 <+> ppInstrMeta metadata-    SRem {..}   -> "srem"  <+> ppTyped operand0 `cma` pp operand1 <+> ppInstrMeta metadata-    URem {..}   -> "urem"  <+> ppTyped operand0 `cma` pp operand1 <+> ppInstrMeta metadata--    FAdd {..}   -> "fadd" <+> ppTyped operand0 `cma` pp operand1 <+> ppInstrMeta metadata-    FSub {..}   -> "fsub" <+> ppTyped operand0 `cma` pp operand1 <+> ppInstrMeta metadata-    FMul {..}   -> "fmul" <+> ppTyped operand0 `cma` pp operand1 <+> ppInstrMeta metadata-    FDiv {..}   -> "fdiv" <+> ppTyped operand0 `cma` pp operand1 <+> ppInstrMeta metadata-    FRem {..}   -> "frem" <+> ppTyped operand0 `cma` pp operand1 <+> ppInstrMeta metadata-    FCmp {..}   -> "fcmp" <+> pp fpPredicate <+> ppTyped operand0 `cma` pp operand1 <+> ppInstrMeta metadata--    Alloca {..} -> "alloca" <+> pp allocatedType <> num <> ppAlign alignment <+> ppInstrMeta metadata-      where num   = case numElements of Nothing -> empty-                                        Just o -> "," <+> ppTyped o-    Store {..}  -> "store" <+> ppTyped value `cma` ppTyped address <> ppAlign alignment-    Load {..}   -> "load" <+> pp argTy `cma` ppTyped address <> ppAlign alignment <+> ppInstrMeta metadata-      where PointerType argTy _ = typeOf address-    Phi {..}    -> "phi" <+> pp type' <+> commas (fmap phiIncoming incomingValues) <+> ppInstrMeta metadata--    ICmp {..}   -> "icmp" <+> pp iPredicate <+> ppTyped operand0 `cma` pp operand1 <+> ppInstrMeta metadata--    c@Call {..} -> ppCall c  <+> ppInstrMeta metadata-    Select {..} -> "select" <+> commas [ppTyped condition', ppTyped trueValue, ppTyped falseValue] <+> ppInstrMeta metadata-    SExt {..}   -> "sext" <+> ppTyped operand0 <+> "to" <+> pp type' <+> ppInstrMeta metadata <+> ppInstrMeta metadata-    ZExt {..}   -> "zext" <+> ppTyped operand0 <+> "to" <+> pp type' <+> ppInstrMeta metadata <+> ppInstrMeta metadata-    FPExt {..}   -> "fpext" <+> ppTyped operand0 <+> "to" <+> pp type' <+> ppInstrMeta metadata <+> ppInstrMeta metadata-    Trunc {..}  -> "trunc" <+> ppTyped operand0 <+> "to" <+> pp type' <+> ppInstrMeta metadata <+> ppInstrMeta metadata-    FPTrunc {..}  -> "fptrunc" <+> ppTyped operand0 <+> "to" <+> pp type' <+> ppInstrMeta metadata <+> ppInstrMeta metadata--    GetElementPtr {..} -> "getelementptr" <+> bounds inBounds <+> commas (pp argTy : fmap ppTyped (address:indices)) <+> ppInstrMeta metadata-      where argTy = getElementType $ typeOf address-    ExtractValue {..} -> "extractvalue" <+> commas (ppTyped aggregate : fmap pp indices') <+> ppInstrMeta metadata--    BitCast {..} -> "bitcast" <+> ppTyped operand0 <+> "to" <+> pp type' <+> ppInstrMeta metadata-    FPToUI {..} -> "fptoui" <+> ppTyped operand0 <+> "to" <+> pp type' <+> ppInstrMeta metadata-    FPToSI {..} -> "fptosi" <+> ppTyped operand0 <+> "to" <+> pp type' <+> ppInstrMeta metadata-    UIToFP {..} -> "uitofp" <+> ppTyped operand0 <+> "to" <+> pp type' <+> ppInstrMeta metadata-    SIToFP {..} -> "sitofp" <+> ppTyped operand0 <+> "to" <+> pp type' <+> ppInstrMeta metadata-    PtrToInt {..} -> "ptrtoint" <+> ppTyped operand0 <+> "to" <+> pp type' <+> ppInstrMeta metadata-    IntToPtr {..} -> "inttoptr" <+> ppTyped operand0 <+> "to" <+> pp type' <+> ppInstrMeta metadata--    InsertElement {..} -> "insertelement" <+> commas [ppTyped vector, ppTyped element, ppTyped index] <+> ppInstrMeta metadata-    ShuffleVector {..} -> "shufflevector" <+> commas [ppTyped operand0, ppTyped operand1, ppTyped mask] <+> ppInstrMeta metadata-    ExtractElement {..} -> "extractelement" <+> commas [ppTyped vector, ppTyped index] <+> ppInstrMeta metadata-    InsertValue {..} -> "insertvalue" <+> commas (ppTyped aggregate : ppTyped element : fmap pp indices') <+> ppInstrMeta metadata--    Fence {..} -> "fence" <+> pp atomicity <+> ppInstrMeta metadata-    AtomicRMW {..} -> "atomicrmw" <+> ppVolatile volatile <+> pp rmwOperation <+> ppTyped address `cma` ppTyped value <+> pp atomicity  <+> ppInstrMeta metadata-    CmpXchg {..} -> "cmpxchg" <+> ppVolatile volatile <+> ppTyped address `cma` ppTyped expected `cma` ppTyped replacement-      <+> pp atomicity <+> pp failureMemoryOrdering <+> ppInstrMeta metadata--    AddrSpaceCast {..} -> "addrspacecast" <+> ppTyped operand0 <+> "to" <+> pp type' <+> ppInstrMeta metadata-    VAArg {..} -> "va_arg" <+> ppTyped argList `cma` pp type' <+> ppInstrMeta metadata--    LandingPad {..} ->-      "landingpad" <+> pp type' <+> ppBool "cleanup" cleanup <+> ppInstrMeta metadata-      <+> commas (fmap pp clauses)-    CatchPad {..} -> "catchpad" <+> "within" <+> pp catchSwitch <+> brackets (commas (map ppTyped args)) <+> ppInstrMeta metadata-    CleanupPad {..} -> "cleanuppad" <+> "within" <+> pp parentPad <+> brackets (commas (map ppTyped args)) <+> ppInstrMeta metadata--    where-      bounds True = "inbounds"-      bounds False = empty--instance PP CallableOperand where-  pp (Left asm) = error "CallableOperand"-  pp (Right op) = pp op--instance PP LandingPadClause where-  pp = \case-    Catch c  -> "catch" <+> ppTyped c-    Filter c -> "filter" <+> ppTyped c--instance PP [Either GroupID FunctionAttribute] where-  pp x = hsep $ fmap pp x--instance PP (Either GroupID FunctionAttribute) where-  pp (Left gid) = pp gid-  pp (Right fattr) = pp fattr--instance PP Operand where-  pp (LocalReference _ nm) = local' (pp nm)-  pp (ConstantOperand con) = pp con-  pp (MetadataOperand mdata) = pp mdata--instance PP Metadata where-  pp (MDString str) = "!" <> dquotes (text (decodeShortUtf8 str))-  pp (MDNode node) = pp node-  pp (MDValue operand) = ppTyped operand--ppDINode :: [Char] -> [([Char], Maybe Doc)] -> Doc-ppDINode name attrs = "!" <> pp name <> parens (commas (mapMaybe (\(k, mayV) -> fmap (\v -> pp k <> ":" <+> v) mayV) attrs))--ppDIArray :: [Doc] -> Maybe Doc-ppDIArray [] = Nothing-ppDIArray xs = Just ("!" <> braces (commas xs))--instance PP a => PP (MDRef a) where-  pp (MDInline a) = pp a-  pp (MDRef ref) = pp ref--instance PP MDNode where-  pp (MDTuple xs) = "!" <> braces (commas (map ppMetadata xs))-  pp (DIExpression e) = pp e-  pp (DIGlobalVariableExpression e) = pp e-  pp (DILocation l) = pp l-  pp (DIMacroNode m) = pp m-  pp (DINode n) = pp n--instance PP DIExpression where-  pp (Expression os) = "!DIExpression" <> parens (commas (concatMap ppDWOp os))--ppDWOp :: DWOp -> [Doc]-ppDWOp o = case o of-  DwOpFragment DW_OP_LLVM_Fragment {..} -> ["DW_OP_LLVM_fragment", pp offset, pp size]-  DW_OP_StackValue -> ["DW_OP_stack_value"]-  DW_OP_Swap -> ["DW_OP_swap"]-  DW_OP_ConstU c -> ["DW_OP_constu", pp c]-  DW_OP_PlusUConst c -> ["DW_OP_plus_uconst", pp c]-  DW_OP_Plus -> ["DW_OP_plus"]-  DW_OP_Minus -> ["DW_OP_minus"]-  DW_OP_Mul -> ["DW_OP_mul"]-  DW_OP_Deref -> ["DW_OP_deref"]-  DW_OP_XDeref -> ["DW_OP_xderef"]--instance PP DIGlobalVariableExpression where-  pp e = ppDINode "DIGlobalVariableExpression"-    [ ("var", Just (pp (var e)))-    , ("expr", Just (pp (expr e)))-    ]--instance PP DILocation where-  pp (Location line col scope) =-    ppDINode "DILocation" [("line", Just (pp line)), ("column", Just (pp col)), ("scope", Just (pp scope))]--instance PP DIMacroNode where-  pp DIMacro {..} = ppDINode "DIMacro"-    [("type", Just (pp info)), ("line", Just (pp line)), ("name", ppSbs name), ("value", ppSbs value)]-  pp DIMacroFile {..} = ppDINode "DIMacroFile"-    [ ("line", Just (pp line))-    , ("file", Just (pp file))-    , ("nodes", ppDIArray (map pp elements))-    ]--instance PP DIMacroInfo where-  pp Define = "DW_MACINFO_define"-  pp Undef = "DW_MACINFO_undef"--instance PP DINode where-  pp (DIEnumerator e) = pp e-  pp (DIImportedEntity e) = pp e-  pp (DIObjCProperty p) = pp p-  pp (DIScope s) = pp s-  pp (DISubrange r) = pp r-  pp (DITemplateParameter p) = pp p-  pp (DIVariable v) = pp v--instance PP DILocalScope where-  pp (DILexicalBlockBase b) = pp b-  pp (DISubprogram p) = pp p--instance PP DIEnumerator where-  pp (Enumerator val name) = ppDINode "DIEnumerator" [("name", ppSbs name), ("value", Just (pp val))]--instance PP DIImportedEntity where-  pp ImportedEntity {..} = ppDINode "DIImportedEntity"-    [ ("tag", Just (pp tag))-    , ("scope", Just (pp scope))-    , ("name", ppSbs name)-    , ("entity", fmap pp entity)-    , ("file", fmap pp file)-    , ("line", Just (pp line))-    ]--instance PP ImportedEntityTag where-  pp ImportedModule = "DW_TAG_imported_module"-  pp ImportedDeclaration = "DW_TAG_imported_declaration"--instance PP DIObjCProperty where-  pp ObjCProperty {..} = ppDINode "DIObjCProperty"-    [ ("name", ppSbs name)-    , ("file", fmap pp file)-    , ("line", Just (pp line))-    , ("setter", ppSbs getterName)-    , ("getter", ppSbs setterName)-    , ("attributes", Just (pp attributes))-    , ("type", fmap pp type')-    ]--instance PP DIScope where-  pp (DICompileUnit cu) = pp cu-  pp (DIFile f) = pp f-  pp (DILocalScope s) = pp s-  pp (DIModule m) = pp m-  pp (DINamespace ns) = pp ns-  pp (DIType t) = pp t--instance PP DISubrange where-  pp Subrange {..} = ppDINode "DISubrange" [("count", Just (pp count)), ("lowerBound", Just (pp lowerBound))]--instance PP DITemplateParameter where-  pp DITemplateTypeParameter {..} = ppDINode "DITemplateTypeParameter"-    [ ("name", ppSbs name), ("type", Just (pp type')) ]-  pp DITemplateValueParameter {..} = ppDINode "DITemplateValueParameter"-   [ ("tag", ppTemplateValueParameterTag tag)-   , ("name", ppSbs name)-   , ("type", Just (pp type'))-   , ("value", Just (pp value))-   ]--ppTemplateValueParameterTag :: TemplateValueParameterTag -> Maybe Doc-ppTemplateValueParameterTag TemplateValueParameter = Nothing-ppTemplateValueParameterTag GNUTemplateTemplateParam = Just "DW_TAG_GNU_template_template_param"-ppTemplateValueParameterTag GNUTemplateParameterPack = Just "DW_TAG_GNU_template_parameter_pack"--instance PP DIVariable where-  pp (DIGlobalVariable v) = pp v-  pp (DILocalVariable v) = pp v--instance PP DICompileUnit where-  pp cu@CompileUnit {..} = "distinct" <+> ppDINode "DICompileUnit"-    [ ("language", Just (pp language))-    , ("file", Just (pp file))-    , ("producer", ppSbs producer)-    , ("isOptimized", Just (pp optimized))-    , ("flags", ppSbs flags)-    , ("runtimeVersion", Just (pp runtimeVersion))-    , ("splitDebugFileName", ppSbs splitDebugFileName)-    , ("emissionKind", Just (pp emissionKind))-    , ("enums", ppDIArray (map pp enums))-    , ("retainedTypes", ppDIArray (map ppEither retainedTypes))-    , ("globals", ppDIArray (map pp globals))-    , ("imports", ppDIArray (map pp imports))-    , ("macros", ppDIArray (map pp macros))-    , ("dwoId", Just (pp dWOId))-    , ("splitDebugInlining", Just (pp splitDebugInlining))-    , ("debugInfoForProfiling", Just (pp debugInfoForProfiling))-    , ("gnuPubnames", Just (pp gnuPubnames))-    ]--instance PP DebugEmissionKind where-  pp NoDebug = "NoDebug"-  pp FullDebug = "FullDebug"-  pp LineTablesOnly = "LineTablesOnly"--instance PP DIFile where-  pp (File {..}) = ppDINode "DIFile" $-    [ ("filename", Just (dquotes (pp filename)))-    , ("directory", Just (dquotes (pp directory)))-    , ("checksum", ppSbs checksum)-    , ("checksumkind", Just (pp checksumKind))-    ]--instance PP DIModule where-  pp O.Module {..} = ppDINode "DIModule"-    [ ("scope", Just (maybe "null" pp scope))-    , ("name", ppSbs name)-    , ("configMacros", ppSbs configurationMacros)-    , ("includePath", ppSbs includePath)-    , ("isysroot", ppSbs isysRoot)-    ]--instance PP DINamespace where-  pp Namespace {..} = ppDINode "DINamespace"-    [ ("name", ppSbs name)-    , ("scope", Just (maybe "null" pp scope))-    , ("exportSymbols", Just (pp exportSymbols))-    ]--instance PP DIType where-  pp (DIBasicType t) = pp t-  pp (DICompositeType t) = pp t-  pp (DIDerivedType t) = pp t-  pp (DISubroutineType t) = pp t--instance PP DILexicalBlockBase where-  pp DILexicalBlock {..} = ppDINode "DILexicalBlock"-    [ ("scope", Just (pp scope))-    , ("file", fmap pp file)-    , ("line", Just (pp line))-    , ("column", Just (pp column))-    ]-  pp DILexicalBlockFile {..} = ppDINode "DILexicalBlockFile"-    [ ("scope", Just (pp scope)), ("file", fmap pp file), ("discriminator", Just (pp discriminator)) ]--ppSbs :: BS.ShortByteString -> Maybe Doc-ppSbs s-  | SBF.null s = Nothing-  | otherwise = Just (dquotes (pp s))--instance PP DISubprogram where-  pp Subprogram {..} = ppMaybe (if definition then Just ("distinct " :: [Char]) else Nothing) <>-   ppDINode "DISubprogram"-   [ ("name", ppSbs name)-   , ("linkageName", ppSbs linkageName)-   , ("scope", fmap pp scope)-   , ("file", fmap pp file)-   , ("line", Just (pp line))-   , ("type", fmap pp type')-   , ("isLocal", Just (pp localToUnit))-   , ("isDefinition", Just (pp definition))-   , ("scopeLine", Just (pp scopeLine))-   , ("containingType", fmap pp containingType)-   , ("virtuality", ppVirtuality virtuality)-   , ("virtualIndex", Just (pp virtualityIndex))-   , ("thisAdjustment", Just (pp thisAdjustment))-   , ("flags", ppDIFlags flags)-   , ("isOptimized", Just (pp optimized))-   , ("unit", fmap pp unit)-   , ("templateParams", ppDIArray (map pp templateParams))-   , ("declaration", fmap pp declaration)-   , ("variables", ppDIArray (map pp variables))-   , ("thrownTypes", ppDIArray (map pp thrownTypes))-   ]--ppVirtuality :: Virtuality -> Maybe Doc-ppVirtuality NoVirtuality = Nothing-ppVirtuality Virtual = Just "DW_VIRTUALITY_virtual"-ppVirtuality PureVirtual = Just "DW_VIRTUALITY_pure_virtual"--instance PP ChecksumKind where-  pp None = "CSK_None"-  pp MD5 = "CSK_MD5"-  pp SHA1 = "CSK_SHA1"--instance PP DIBasicType where-  pp (BasicType {..}) = ppDINode "DIBasicType"-    [ ("tag", Just (pp tag))-    , ("name", ppSbs name)-    , ("size", Just (pp sizeInBits))-    , ("align", Just (pp alignInBits))-    , ("encoding", fmap pp encoding)-    ]--instance PP BasicTypeTag where-  pp BaseType = "DW_TAG_base_type"-  pp UnspecifiedType = "DW_TAG_unspecified_type"--instance PP Encoding where-  pp e = case e of-    AddressEncoding -> "DW_ATE_address"-    BooleanEncoding -> "DW_ATE_boolean"-    FloatEncoding -> "DW_ATE_float"-    SignedEncoding -> "DW_ATE_signed"-    SignedCharEncoding -> "DW_ATE_signed_char"-    UnsignedEncoding -> "DW_ATE_unsigned"-    UnsignedCharEncoding -> "DW_ATE_unsigned_char"--ppDIFlags :: [DIFlag] -> Maybe Doc-ppDIFlags [] = Nothing-ppDIFlags flags = Just (hsep (punctuate (char '|') (map pp flags)))--instance PP DIFlag where-  pp flag = "DIFlag" <> fromString (flagName flag)-    where-      flagName (Accessibility f) = show f-      flagName (InheritanceFlag f) = show f-      flagName VirtualFlag = "Virtual"-      flagName f = show f---ppEither :: (PP a, PP b) => MDRef (Either a b) -> Doc-ppEither (MDRef r) = pp r-ppEither (MDInline e) = either pp pp e--instance PP DICompositeType where-  pp DIArrayType {..} = ppDINode "DICompositeType"-    [ ("tag", Just "DW_TAG_array_type")-    , ("elements", ppDIArray (map pp subscripts))-    , ("baseType", fmap pp elementTy)-    , ("size", Just (pp sizeInBits))-    , ("align", Just (pp alignInBits))-    , ("flags", ppDIFlags flags)-    ]-  pp DIClassType {..} = ppDINode "DICompositeType"-    [ ("tag", Just "DW_TAG_class_type")-    , ("scope", fmap pp scope)-    , ("name", ppSbs name)-    , ("file", fmap pp file)-    , ("line", Just (pp line))-    , ("flags", ppDIFlags flags)-    , ("baseType", fmap pp derivedFrom)-    , ("elements", ppDIArray (map ppEither elements))-    , ("vtableHolder", fmap pp vtableHolder)-    , ("templateParams", ppDIArray (map pp templateParams))-    , ("identifier", ppSbs identifier)-    , ("size", Just (pp sizeInBits))-    , ("align", Just (pp alignInBits))-    ]-  pp DIEnumerationType {..} = ppDINode "DICompositeType"-    [ ("tag", Just "DW_TAG_enumeration_type")-    , ("name", ppSbs name)-    , ("file", fmap pp file)-    , ("line", Just (pp line))-    , ("size", Just (pp sizeInBits))-    , ("align", Just (pp alignInBits))-    , ("elements", Just ("!" <> braces (commas (map pp values))))-    , ("scope", fmap pp scope)-    , ("identifier", ppSbs identifier)-    , ("baseType", fmap pp baseType)-    ]-  pp DIStructureType {..} = ppDINode "DICompositeType"-    [ ("tag", Just "DW_TAG_structure_type")-    , ("scope", fmap pp scope)-    , ("name", ppSbs name)-    , ("file", fmap pp file)-    , ("line", Just (pp line))-    , ("flags", ppDIFlags flags)-    , ("baseType", fmap pp derivedFrom)-    , ("elements", ppDIArray (map ppEither elements))-    , ("runtimeLang", Just (pp runtimeLang))-    , ("vtableHolder", fmap pp vtableHolder)-    , ("identifier", ppSbs identifier)-    , ("size", Just (pp sizeInBits))-    , ("align", Just (pp alignInBits))-    ]-  pp DIUnionType {..} = ppDINode "DICompositeType"-    [ ("tag", Just "DW_TAG_union_type")-    , ("name", ppSbs name)-    , ("file", fmap pp file)-    , ("line", Just (pp line))-    , ("flags", ppDIFlags flags)-    , ("elements", ppDIArray (map ppEither elements))-    , ("runtimeLang", Just (pp runtimeLang))-    , ("identifier", ppSbs identifier)-    , ("size", Just (pp sizeInBits))-    , ("align", Just (pp alignInBits))-    ]--instance PP DIDerivedType where-  pp DerivedType {..} = ppDINode "DIDerivedType"-    [ ("tag", Just (pp tag))-    , ("name", ppSbs name)-    , ("file", fmap pp file)-    , ("line", Just (pp line))-    , ("scope", fmap pp scope)-    , ("baseType", Just (pp baseType))-    , ("size", Just (pp sizeInBits))-    , ("align", Just (pp alignInBits))-    , ("offset", Just (pp offsetInBits))-    , ("flags", ppDIFlags flags)-    , ("dwarfAddressSpace", fmap pp addressSpace)-    ]--instance PP DerivedTypeTag where-  pp t =-    case t of-      Typedef -> "DW_TAG_typedef"-      O.PointerType -> "DW_TAG_pointer_type"-      PtrToMemberType -> "DW_TAG_ptr_to_member_type"-      ReferenceType -> "DW_TAG_reference_type"-      RValueReferenceType -> "DW_TAG_rvalue_reference_type"-      ConstType -> "DW_TAG_const_type"-      VolatileType -> "DW_TAG_volatile_type"-      RestrictType -> "DW_TAG_restrict_type"-      AtomicType -> "DW_TAG_atomic_type"-      Member -> "DW_TAG_member"-      Inheritance -> "DW_TAG_inheritance"-      Friend -> "DW_TAG_friend"--instance PP DISubroutineType where-  pp SubroutineType {..} = ppDINode "DISubroutineType"-    [ ("flags", ppDIFlags flags)-    , ("cc", Just (pp cc))-    , ("types", Just ("!" <> braces (commas (map ppTy typeArray))))-    ]-    where ppTy Nothing = "null"-          ppTy (Just t) = pp t--instance PP DIGlobalVariable where-  pp O.GlobalVariable {..} = ppDINode "DIGlobalVariable"-    [ ("name", ppSbs name)-    , ("scope", fmap pp scope)-    , ("linkageName", ppSbs linkageName)-    , ("file", fmap pp file)-    , ("line", Just (pp line))-    , ("type", fmap pp type')-    , ("isLocal", Just (pp local))-    , ("isDefinition", Just (pp definition))-    , ("declaration", fmap pp staticDataMemberDeclaration)-    , ("align", Just (pp alignInBits))-    ]--instance PP DILocalVariable where-  pp LocalVariable {..} = ppDINode "DILocalVariable"-    [ ("name", ppSbs name)-    , ("scope", Just (pp scope))-    , ("file", fmap pp file)-    , ("line", Just (pp line))-    , ("type", fmap pp type')-    , ("flags", ppDIFlags flags)-    , ("arg", Just (pp arg))-    , ("align", Just (pp alignInBits))-    ]--instance PP C.Constant where-  pp (C.Int width val) = pp val-  pp (C.Float (F.Double val))      =-    if specialFP val-      then "0x" <> (text . pack) (showHex (doubleToWord val) "")-      else text $ pack $ printf "%6.6e" val-  pp (C.Float (F.Single val))      =-    if specialFP val-      then "0x" <> (text . pack) (showHex (floatToWord val) "")-      else text $ pack $ printf "%6.6e" val-  pp (C.Float (F.Half val))        = text $ pack $ printf "%6.6e" val-  pp (C.Float (F.Quadruple val _)) = text $ pack $ printf "%6.6e" val-  pp (C.Float (F.X86_FP80 val _))  = text $ pack $ printf "%6.6e" val-  pp (C.Float (F.PPC_FP128 val _)) = text $ pack $ printf "%6.6e" val--  pp (C.GlobalReference ty nm) = "@" <> pp nm-  pp (C.Vector args) = "<" <+> commas (fmap ppTyped args) <+> ">"--  pp (C.Add {..})    = "add"  <+> ppTyped operand0 `cma` pp operand1-  pp (C.Sub {..})    = "sub"  <+> ppTyped operand0 `cma` pp operand1-  pp (C.Mul {..})    = "mul"  <+> ppTyped operand0 `cma` pp operand1-  pp (C.Shl {..})    = "shl"  <+> ppTyped operand0 `cma` pp operand1-  pp (C.AShr {..})   = "ashr" <+> ppTyped operand0 `cma` pp operand1-  pp (C.LShr {..})   = "lshr" <+> ppTyped operand0 `cma` pp operand1-  pp (C.And {..})    = "and"  <+> ppTyped operand0 `cma` pp operand1-  pp (C.Or {..})     = "or"   <+> ppTyped operand0 `cma` pp operand1-  pp (C.Xor {..})    = "xor"  <+> ppTyped operand0 `cma` pp operand1-  pp (C.SDiv {..})   = "sdiv"  <+> ppTyped operand0 `cma` pp operand1-  pp (C.UDiv {..})   = "udiv"  <+> ppTyped operand0 `cma` pp operand1-  pp (C.SRem {..})   = "srem"  <+> ppTyped operand0 `cma` pp operand1-  pp (C.URem {..})   = "urem"  <+> ppTyped operand0 `cma` pp operand1--  pp (C.FAdd {..})   = "fadd" <+> ppTyped operand0 `cma` pp operand1-  pp (C.FSub {..})   = "fsub" <+> ppTyped operand0 `cma` pp operand1-  pp (C.FMul {..})   = "fmul" <+> ppTyped operand0 `cma` pp operand1-  pp (C.FDiv {..})   = "fdiv" <+> ppTyped operand0 `cma` pp operand1-  pp (C.FRem {..})   = "frem" <+> ppTyped operand0 `cma` pp operand1-  pp (C.FCmp {..})   = "fcmp" <+> pp fpPredicate <+> ppTyped operand0 `cma` pp operand1-  pp C.ICmp {..}     = "icmp" <+> pp iPredicate <+> ppTyped operand0 `cma` pp operand1--  pp (C.Select {..})  = "select" <+> commas [ppTyped condition', ppTyped trueValue, ppTyped falseValue]-  pp (C.SExt {..})    = "sext" <+> ppTyped operand0 <+> "to" <+> pp type'-  pp (C.ZExt {..})    = "zext" <+> ppTyped operand0 <+> "to" <+> pp type'-  pp (C.FPExt {..})   = "fpext" <+> ppTyped operand0 <+> "to" <+> pp type'-  pp (C.Trunc {..})   = "trunc" <+> ppTyped operand0 <+> "to" <+> pp type'-  pp (C.FPTrunc {..}) = "fptrunc" <+> ppTyped operand0 <+> "to" <+> pp type'--  pp C.FPToUI {..} = "fptoui" <+> ppTyped operand0 <+> "to" <+> pp type'-  pp C.FPToSI {..} = "fptosi" <+> ppTyped operand0 <+> "to" <+> pp type'-  pp C.UIToFP {..} = "uitofp" <+> ppTyped operand0 <+> "to" <+> pp type'-  pp C.SIToFP {..} = "sitofp" <+> ppTyped operand0 <+> "to" <+> pp type'--  pp (C.Struct _ packed elems) =-    let struct = spacedbraces $ commas $ fmap ppTyped elems-    in if packed-         then angleBrackets struct-         else struct--  pp (C.Null constantType) = ppNullInitializer constantType--#if MIN_VERSION_llvm_hs_pure(5,1,3)-  pp (C.AggregateZero constantType) = "zeroinitializer"-#endif--  pp (C.Undef {}) = "undef"-  pp (C.TokenNone {}) = "none"-  pp (C.BlockAddress fn blk) = "blockaddress" <> parens (commas (fmap pp [fn, blk]))--  pp C.Array {..}-    | memberType == (IntegerType 8) = "c" <> (dquotes $ hcat [ppIntAsChar val | C.Int _ val <- memberValues])-    | otherwise = brackets $ commas $ fmap ppTyped memberValues--  pp C.GetElementPtr {..} = "getelementptr" <+> bounds inBounds <+> parens (commas (pp argTy : fmap ppTyped (address:indices)))-    where-      PointerType argTy _ = typeOf address-      bounds True = "inbounds"-      bounds False = empty--  pp C.BitCast {..} = "bitcast" <+> parens (ppTyped operand0 <+> "to" <+> pp type')-  pp C.PtrToInt {..} = "ptrtoint" <+> parens (ppTyped operand0 <+> "to" <+> pp type')-  pp C.IntToPtr {..} = "inttoptr" <+> parens (ppTyped operand0 <+> "to" <+> pp type')-  pp C.AddrSpaceCast {..} = "addrspacecast" <+> parens (ppTyped operand0 <+> "to" <+> pp type')-  pp _ = error "Non-function argument. (Malformed AST)"--instance PP a => PP (Named a) where-  pp (nm := a) = "%" <> pp nm <+> "=" <+> pp a-  pp (Do a) = pp a--instance PP Module where-  pp Module {..} =-    let header = printf "; ModuleID = '%s'" (unShort moduleName) in-    let target = case moduleTargetTriple of-                      Nothing -> mempty-                      Just target -> "target triple =" <+> dquotes (pp target) in-    let layout = case moduleDataLayout of-                      Nothing     -> mempty-                      Just layout -> "target datalayout =" <+> dquotes (pp layout) in-    hlinecat (fromString header : (layout </> target) : (fmap pp moduleDefinitions))--instance PP FP.FloatingPointPredicate where-  pp op = case op of-   FP.False -> "false"-   FP.OEQ   -> "oeq"-   FP.OGT   -> "ogt"-   FP.OGE   -> "oge"-   FP.OLT   -> "olt"-   FP.OLE   -> "ole"-   FP.ONE   -> "one"-   FP.ORD   -> "ord"-   FP.UEQ   -> "ueq"-   FP.UGT   -> "ugt"-   FP.UGE   -> "uge"-   FP.ULT   -> "ult"-   FP.ULE   -> "ule"-   FP.UNE   -> "une"-   FP.UNO   -> "uno"-   FP.True  -> "true"--instance PP IP.IntegerPredicate where-  pp op = case op of-   IP.EQ  -> "eq"-   IP.NE  -> "ne"-   IP.UGT -> "ugt"-   IP.UGE -> "uge"-   IP.ULT -> "ult"-   IP.ULE -> "ule"-   IP.SGT -> "sgt"-   IP.SGE -> "sge"-   IP.SLT -> "slt"-   IP.SLE -> "sle"--instance PP Atomicity where-  pp (scope, order) =-    pp scope <+> pp order--instance PP SynchronizationScope where-  pp = \case-    SingleThread -> "syncscope(\"singlethread\")"-    System -> mempty--instance PP MemoryOrdering where-  pp = \case-    Unordered              -> "unordered"-    Monotonic              -> "monotonic"-    Acquire                -> "acquire"-    Release                -> "release"-    AcquireRelease         -> "acq_rel"-    SequentiallyConsistent -> "seq_cst"--instance PP RMW.RMWOperation where-  pp = \case-    RMW.Xchg -> "xchg"-    RMW.Add -> "add"-    RMW.Sub -> "sub"-    RMW.And -> "and"-    RMW.Nand -> "nand"-    RMW.Or -> "or"-    RMW.Xor -> "xor"-    RMW.Max -> "max"-    RMW.Min -> "min"-    RMW.UMax -> "umax"-    RMW.UMin -> "umin"--instance PP DataLayout where-  pp x = pp (BL.unpack (dataLayoutToString x))------------------------------------------------------------------------------------ Special Case Hacks----------------------------------------------------------------------------------escape :: Char -> Doc-escape '"'  = "\\22"-escape '\\' = "\\\\"-escape c    = if isAscii c && not (isControl c)-              then char c-              else "\\" <> hex c-    where-        hex :: Char -> Doc-        hex = pad0 . ($ []) . showHex . ord-        pad0 :: String -> Doc-        pad0 [] = "00"-        pad0 [x] = "0" <> char x-        pad0 xs = text (pack xs)--ppVolatile :: Bool -> Doc-ppVolatile True = "volatile"-ppVolatile False = mempty--ppIntAsChar :: Integral a => a -> Doc-ppIntAsChar = escape . chr . fromIntegral--ppAlign :: Word32 -> Doc-ppAlign x | x == 0    = empty-          | otherwise = ", align" <+> pp x---- print an operand and its type-ppTyped :: (PP a, Typed a) => a -> Doc-ppTyped a = pp (typeOf a) <+> pp a--ppCommaTyped :: (PP a, Typed a) => a -> Doc-ppCommaTyped a = pp (typeOf a) `cma` pp a--phiIncoming :: (Operand, Name) -> Doc-phiIncoming (op, nm) = brackets (pp op `cma` (local' (pp nm)))--ppParams :: (a -> Doc) -> ([a], Bool) -> Doc-ppParams ppParam (ps, varrg) = parens . commas $ fmap ppParam ps ++ vargs-    where-        vargs = if varrg then ["..."] else []--ppFunctionArgumentTypes :: Type -> Doc-ppFunctionArgumentTypes FunctionType {..} = ppParams pp (argumentTypes, isVarArg)-ppFunctionArgumentTypes _ = error "Non-function argument. (Malformed AST)"--ppNullInitializer :: Type -> Doc-ppNullInitializer PointerType {..} = "zeroinitializer"-ppNullInitializer StructureType {..} = "zeroinitializer"-ppNullInitializer FunctionType {..} = "zeroinitializer"-ppNullInitializer ArrayType {..} = "zeroinitializer"-ppNullInitializer _ = error "Non-pointer argument. (Malformed AST)"--ppCall :: Instruction -> Doc-ppCall Call { function = Right f,..}-  = tail <+> "call" <+> pp callingConvention <+> pp returnAttributes <+> pp resultType <+> ftype-    <+> pp f <> parens (commas $ fmap pp arguments) <+> pp functionAttributes-    where-      (functionType@FunctionType {..}) = referencedType (typeOf f)-      ftype = if isVarArg-              then ppFunctionArgumentTypes functionType-              else empty-      referencedType (PointerType t _) = referencedType t-      referencedType t                 = t--      tail = case tailCallKind of-        Just Tail -> "tail"-        Just MustTail -> "musttail"-        Just NoTail -> "notail"-        Nothing -> empty-ppCall Call { function = Left (IA.InlineAssembly {..}), ..}-  = tail <+> "call" <+> pp callingConvention <+> pp returnAttributes <+> pp type'-    <+> "asm" <+> sideeffect' <+> align' <+> dialect' <+> dquotes (text (pack (BL.unpack assembly))) <> ","-    <+> dquotes (pp constraints) <> parens (commas $ fmap pp arguments) <+> pp functionAttributes-    where-      tail = case tailCallKind of-        Just Tail -> "tail"-        Just MustTail -> "musttail"-        Just NoTail -> "notail"-        Nothing -> empty-      -- If multiple keywords appear the ‘sideeffect‘ keyword must come first,-      -- the ‘alignstack‘ keyword second and the ‘inteldialect‘ keyword last.-      sideeffect' = if hasSideEffects then "sideeffect" else ""-      align' = if alignStack then "alignstack" else ""-      -- ATTDialect is assumed if not specified-      dialect' = case dialect of IA.ATTDialect -> ""; IA.IntelDialect -> "inteldialect"-ppCall x = error "Non-callable argument. (Malformed AST)"---- Differs from Call in record name conventions only so needs a seperate almost--- identical function. :(-ppInvoke :: Terminator -> Doc-ppInvoke Invoke { function' = Right f,..}-  = "invoke" <+> pp callingConvention' <+> pp resultType <+> ftype-    <+> pp f <> parens (commas $ fmap pp arguments') <+> pp functionAttributes'-    where-      (functionType@FunctionType {..}) = referencedType (typeOf f)-      ftype = if isVarArg-              then ppFunctionArgumentTypes functionType-              else empty-      referencedType (PointerType t _) = referencedType t-      referencedType t                 = t-ppInvoke x = error "Non-callable argument. (Malformed AST)"--ppSingleBlock :: BasicBlock -> Doc-ppSingleBlock (BasicBlock nm instrs term) = (vcat $ (fmap pp instrs) ++ [pp term])---- According to <https://stackoverflow.com/a/7002812/3877993> this is--- the best way to cast floats to words.--cast :: (MArray (STUArray s) a (ST s),-         MArray (STUArray s) b (ST s)) => a -> ST s b-cast x = newArray (0 :: Int, 0) x >>= castSTUArray >>= flip readArray 0--doubleToWord :: Double -> Word64-doubleToWord x = runST (cast x)--floatToWord :: Float -> Word32-floatToWord x = runST (cast x)--specialFP :: RealFloat a => a -> Bool-specialFP f = isNaN f || f == 1 / 0 || f == - 1 / 0--ppInstrMeta :: InstructionMetadata -> Doc-ppInstrMeta [] = mempty-ppInstrMeta xs = "," <> pp xs------------------------------------------------------------------------------------ Toplevel------------------------------------------------------------------------------------ | Pretty print a LLVM module-ppllvm :: Module -> Text-ppllvm = displayT . renderPretty 0.4 100 . pp---- | Pretty print a printable LLVM expression-ppll :: PP a => a -> Text-ppll = displayT . renderPretty 0.4 100 . pp+  ppllvm,+  ppll,+) where++import Prelude hiding ((<$>))+import GHC.Word++import LLVM.AST.Typed++import LLVM.AST+import LLVM.AST.Global+import LLVM.AST.Type++import LLVM.DataLayout+import LLVM.AST.Attribute+import LLVM.AST.DataLayout+import LLVM.AST.COMDAT+import qualified LLVM.AST.Linkage as L+import qualified LLVM.AST.Visibility as V+import qualified LLVM.AST.CallingConvention as CC+import qualified LLVM.AST.Constant as C+import qualified LLVM.AST.FloatingPointPredicate as FP+import qualified LLVM.AST.IntegerPredicate as IP+import qualified LLVM.AST.InlineAssembly as IA+import qualified LLVM.AST.AddrSpace as AS+import qualified LLVM.AST.Float as F+import qualified LLVM.AST.RMWOperation as RMW+import LLVM.AST.Operand hiding (DIGLobalVariable(..), GlobalVariable, Module, NoReturn, PointerType)+import qualified LLVM.AST.Operand as O+import LLVM.AST.ParameterAttribute as PA+import LLVM.AST.FunctionAttribute as FA++import Data.String++import Text.Printf+import Data.Text.Lazy.Encoding+import Data.Text.Lazy (Text, pack, unpack)+import qualified Data.ByteString.Short as SBF+import qualified Data.ByteString.Lazy.Char8 as BF+import Data.ByteString.Lazy (fromStrict)+import Data.ByteString.Internal (w2c)+import Data.Text.Prettyprint.Doc+import qualified Data.Text.Prettyprint.Doc as P+import Data.Text.Prettyprint.Doc.Render.Text++import qualified Data.ByteString.Char8 as BL+import qualified Data.ByteString.Short as BS+import Data.Char (chr, ord, isAscii, isControl, isLetter, isDigit)+import Data.Foldable (toList)+import Data.Int+import Data.List (intersperse)+import Data.Maybe (isJust, mapMaybe)+-- import Data.Monoid ((<>))+import Numeric (showHex)++import Data.Array.Unsafe+import Data.Array.MArray+import Data.Array.ST+import Control.Monad.ST++-------------------------------------------------------------------------------+-- Utils+-------------------------------------------------------------------------------++parensIf ::  Bool -> Doc ann -> Doc ann+parensIf True = parens+parensIf False = id++commas :: [Doc ann] -> Doc ann+commas  = hsep . punctuate (pretty ',')++colons :: [Doc ann] -> Doc ann+colons  = hcat . intersperse (pretty ':')++hlinecat :: [Doc ann] -> Doc ann+hlinecat = vcat . intersperse softbreak+  where+    softbreak = group hardline++wrapbraces :: Doc ann -> Doc ann -> Doc ann+wrapbraces leadIn x = (leadIn <> pretty '{') <> line' <> x <> line' <> pretty '}'++angleBrackets :: Doc ann -> Doc ann+angleBrackets x = pretty '<' <> x <> pretty '>'++spacedbraces :: Doc ann -> Doc ann+spacedbraces x = pretty '{' <+> x <+> pretty '}'++local' :: Doc ann -> Doc ann+local' a = "%" <> a++global :: Doc ann -> Doc ann+global a = "@" <> a++label :: Doc ann -> Doc ann+label a = "label" <+> "%" <> a++cma :: Doc ann -> Doc ann -> Doc ann -- <,> does not work :(+a `cma` b = a <> "," <+> b++-------------------------------------------------------------------------------+-- Classes+-------------------------------------------------------------------------------++-- class Pretty p where+--   pretty :: p -> Doc++ppMaybe :: Pretty a => Maybe a -> Doc ann+ppMaybe (Just x) = pretty x+ppMaybe Nothing = mempty++ppBool :: Doc ann -> Bool -> Doc ann+ppBool x True = x+ppBool x False = mempty++-- XXX: horrible hack+unShort :: BS.ShortByteString -> [Char]+unShort xs = fmap (toEnum . fromIntegral) $ BS.unpack xs++short :: BS.ShortByteString -> Doc ann+short x = pretty (pack (unShort x))++decodeShortUtf8 :: SBF.ShortByteString -> Text+decodeShortUtf8 = decodeUtf8 . fromStrict . SBF.fromShort++-- instance Pretty Word8 where+--   pretty x = int (fromIntegral x)++-- instance Pretty Word16 where+--   pretty x = int (fromIntegral x)++-- instance Pretty Word32 where+--   pretty x = int (fromIntegral x)++-- instance Pretty Word64 where+--   pretty x = int (fromIntegral x)++-- instance Pretty Int32 where+--   pretty x = int (fromIntegral x)++-- instance Pretty Int64 where+--   pretty x = int (fromIntegral x)++-- instance Pretty Integer where+--   pretty = integer++instance Pretty BS.ShortByteString where+  pretty = pretty . unShort++-- instance Pretty [Char] where+--   pretty = text . pack++-- instance Pretty Bool where+--   pretty True = "true"+--   pretty False = "false"++ppBoolean :: Bool -> Doc ann+ppBoolean True = "true"+ppBoolean False = "false"++instance Pretty Name where+  pretty (Name nm)+    | BS.null nm = dquotes mempty+    | isFirst first && all isRest name = pretty (pack name)+    | otherwise = dquotes . hcat . map escape $ name+    where+        name = unShort nm+        first = head name+        isFirst c = isLetter c || c == '-' || c == '_' || c == '$' || c == '.'+        isRest c = isDigit c || isFirst c+  pretty (UnName x) = pretty ( (fromIntegral x) :: Int)++instance Pretty Parameter where+  pretty (Parameter ty (UnName _) attrs) = pretty ty <+> ppParamAttributes attrs+  pretty (Parameter ty name attrs) = pretty ty <+> ppParamAttributes attrs <+> local' (pretty name)++ppParamAttributes :: [ParameterAttribute] -> Doc ann+ppParamAttributes pas = hsep $ fmap pretty pas++-- TODO: Auto instance+-- instance Pretty [ParameterAttribute] where+--   pretty x = hsep $ fmap pretty x++-- instance Pretty ([Parameter], Bool) where+--   pretty (params, False) = commas (fmap pretty params)+--   pretty (params, True) = "TODO" XXX: variadic case++-- instance Pretty (Operand, [ParameterAttribute]) where+--   pretty (op, attrs) = pretty (typeOf op) <+> pretty attrs <+> pretty op++ppArguments :: (Operand, [ParameterAttribute]) -> Doc ann+ppArguments (op, attrs) = pretty (typeOf op) <+> ppParamAttributes attrs <+> pretty op++instance Pretty UnnamedAddr where+  pretty LocalAddr = "local_unnamed_addr"+  pretty GlobalAddr = "unnamed_addr"++instance Pretty Type where+  pretty (IntegerType width) = "i" <> pretty width+  pretty (FloatingPointType HalfFP)      = "half"+  pretty (FloatingPointType FloatFP )    = "float"+  pretty (FloatingPointType DoubleFP)    = "double"+  pretty (FloatingPointType FP128FP)     = "fp128"+  pretty (FloatingPointType X86_FP80FP)  = "x86_fp80"+  pretty (FloatingPointType PPC_FP128FP) = "ppc_fp128"++  pretty VoidType = "void"+  pretty (PointerType ref (AS.AddrSpace addr))+    | addr == 0 = pretty ref <> "*"+    | otherwise = pretty ref <+> "addrspace" <> parens (pretty addr) <> "*"+  pretty ft@(FunctionType {..}) = pretty resultType <+> ppFunctionArgumentTypes ft+  pretty (VectorType {..}) = "<" <> pretty nVectorElements <+> "x" <+> pretty elementType <> ">"+  pretty (StructureType {..}) = if isPacked+                               then "<{" <> (commas $ fmap pretty elementTypes ) <> "}>"+                               else  "{" <> (commas $ fmap pretty elementTypes ) <> "}"+  pretty (ArrayType {..}) = brackets $ pretty nArrayElements <+> "x" <+> pretty elementType+  pretty (NamedTypeReference name) = "%" <> pretty name+  pretty MetadataType = "metadata"+  pretty TokenType = "token"+  pretty LabelType = "label"++instance Pretty Global where+  pretty Function {..} =+      case basicBlocks of+        [] ->+          ("declare" <+> pretty linkage <+> pretty callingConvention+            <+> ppReturnAttributes returnAttributes <+> pretty returnType <+> global (pretty name)+            <> ppParams (pretty . typeOf) parameters <+> ppFunctionAttributes functionAttributes <+> align <+> gcName <+> pre)++        -- single unnamed block is special cased, and won't parse otherwise... yeah good times+        [b@(BasicBlock (UnName _) _ _)] ->+            ("define" <+> pretty linkage <+> pretty callingConvention+              <+> ppReturnAttributes returnAttributes <+> pretty returnType <+> global (pretty name)+              <> ppParams pretty parameters <+> ppFunctionAttributes functionAttributes <+> align <+> gcName <+> pre)+            `wrapbraces` (indent 2 $ ppSingleBlock b)++        bs ->+          ("define" <+> pretty linkage <+> pretty callingConvention+            <+> ppReturnAttributes returnAttributes <+> pretty returnType <+> global (pretty name)+            <> ppParams pretty parameters <+> ppFunctionAttributes functionAttributes <+> align <+> gcName <+> pre)+          `wrapbraces` (vcat $ fmap pretty bs)+    where+      pre = case prefix of+              Nothing  -> mempty+              Just con -> "prefix" <+> ppTyped con+      align | alignment == 0    = mempty+            | otherwise = "align" <+> pretty alignment+      gcName = maybe mempty (\n -> "gc" <+> dquotes (pretty $ pack n)) (fmap unShort garbageCollectorName)++  pretty GlobalVariable {..} = global (pretty name) <+> "=" <+> ppLinkage hasInitializer linkage <+> ppMaybe unnamedAddr+                             <+> addrSpace' <+> kind <+> pretty type' <+> ppMaybe initializer <> ppAlign alignment+    where+      hasInitializer = isJust initializer+      addrSpace' =+        case addrSpace of+          AS.AddrSpace addr+            | addr == 0 -> mempty+            | otherwise -> "addrspace" <> parens (pretty addr)+      kind | isConstant = "constant"+           | otherwise  = "global"++  pretty GlobalAlias {..} = global (pretty name) <+> "=" <+> pretty linkage <+> ppMaybe unnamedAddr <+> "alias" <+> pretty typ `cma` ppTyped aliasee+    where+      typ = getElementType type'++ppFunctionAttribute :: Either GroupID FunctionAttribute -> Doc ann+ppFunctionAttribute (Left grpId) = pretty grpId+ppFunctionAttribute (Right fA) = pretty fA++ppFunctionAttributes :: [Either GroupID FunctionAttribute] -> Doc ann+ppFunctionAttributes attribs = hsep $ fmap ppFunctionAttribute attribs++ppMetadata :: Maybe Metadata -> Doc ann+ppMetadata Nothing = "null"+ppMetadata (Just m) = pretty m++instance Pretty Definition where+  pretty (GlobalDefinition x) = pretty x+  pretty (TypeDefinition nm ty) = local' (pretty nm) <+> "=" <+> "type" <+> maybe "opaque" pretty ty+  pretty (FunctionAttributes gid attrs) = "attributes" <+> pretty gid <+> "=" <+> braces (hsep (fmap ppAttrInGroup attrs))+  pretty (NamedMetadataDefinition nm meta) = "!" <> short nm <+> "=" <+> "!" <> braces (commas (fmap pretty meta))+  pretty (MetadataNodeDefinition node meta) = pretty node <+> "=" <+> pretty meta+  pretty (ModuleInlineAssembly asm) = "module asm" <+> dquotes (pretty (pack (BL.unpack asm)))+  pretty (COMDAT name selKind) = "$" <> short name <+> "=" <+> "comdat" <+> pretty selKind++instance Pretty SelectionKind where+  pretty Any = "any"+  pretty ExactMatch = "exactmatch"+  pretty Largest = "largest"+  pretty NoDuplicates = "noduplicates"+  pretty SameSize = "samesize"++ppAttrInGroup :: FunctionAttribute -> Doc ann+ppAttrInGroup = \case+  StackAlignment n -> "alignstack=" <> pretty n+  attr -> pretty attr++instance Pretty FunctionAttribute where+  pretty = \case+   NoReturn            -> "noreturn"+   NoUnwind            -> "nounwind"+   FA.ReadNone         -> "readnone"+   FA.ReadOnly         -> "readonly"+   FA.WriteOnly        -> "writeonly"+   NoInline            -> "noinline"+   AlwaysInline        -> "alwaysinline"+   MinimizeSize        -> "minsize"+   OptimizeForSize     -> "optsize"+   OptimizeNone        -> "optnone"+   SafeStack           -> "safestack"+   StackProtect        -> "ssp"+   StackProtectReq     -> "sspreq"+   StackProtectStrong  -> "sspstrong"+   NoRedZone           -> "noredzone"+   NoImplicitFloat     -> "noimplicitfloat"+   Naked               -> "naked"+   InlineHint          -> "inlinehint"+   StackAlignment n    -> "alignstack" <> parens (pretty n)+   ReturnsTwice        -> "returns_twice"+   UWTable             -> "uwtable"+   NonLazyBind         -> "nonlazybind"+   Builtin             -> "builtin"+   NoBuiltin           -> "nobuiltin"+   Cold                -> "cold"+   JumpTable           -> "jumptable"+   NoDuplicate         -> "noduplicate"+   SanitizeAddress     -> "sanitize_address"+   SanitizeThread      -> "sanitize_thread"+   SanitizeMemory      -> "sanitize_memory"+   SanitizeHWAddress   -> "sanitize_hwaddress"+   NoRecurse           -> "norecurse"+   Convergent          -> "convergent"+   ArgMemOnly          -> "argmemonly"+   InaccessibleMemOnly -> "inaccessiblememonly"+   AllocSize a Nothing -> "allocsize" <> parens (pretty a)+   AllocSize a (Just b) -> "allocsize" <> parens (commas [pretty a, pretty b])+   InaccessibleMemOrArgMemOnly -> "inaccessiblemem_or_argmemonly"+   FA.StringAttribute k v -> dquotes (short k) <> "=" <> dquotes (short v)+   Speculatable        -> "speculatable"+   StrictFP            -> "strictfp"++instance Pretty ParameterAttribute where+  pretty = \case+    ZeroExt                    -> "zeroext"+    SignExt                    -> "signext"+    InReg                      -> "inreg"+    SRet                       -> "sret"+    Alignment word             -> "align" <+> pretty word+    NoAlias                    -> "noalias"+    ByVal                      -> "byval"+    NoCapture                  -> "nocapture"+    Nest                       -> "nest"+    PA.ReadNone                -> "readnone"+    PA.ReadOnly                -> "readonly"+    PA.WriteOnly               -> "writeonly"+    InAlloca                   -> "inalloca"+    NonNull                    -> "nonnull"+    Dereferenceable word       -> "dereferenceable" <> parens (pretty word)+    DereferenceableOrNull word -> "dereferenceable_or_null" <> parens (pretty word)+    Returned                   -> "returned"+    SwiftSelf                  -> "swiftself"+    SwiftError                 -> "swifterror"+    PA.StringAttribute k v -> dquotes (short k) <> "=" <> dquotes (short v)++instance Pretty CC.CallingConvention where+  pretty = \case+   CC.Numbered word -> "cc" <+> pretty word+   CC.C             -> "ccc"+   CC.Fast          -> "fastcc"+   CC.Cold          -> "coldcc"+   CC.GHC           -> "cc 10"+   CC.HiPE          -> "cc 11"+   CC.WebKit_JS     -> "webkit_jscc"+   CC.AnyReg        -> "anyregcc"+   CC.PreserveMost  -> "preserve_mostcc"+   CC.PreserveAll   -> "preserve_allcc"+   CC.Swift         -> "swiftcc"+   CC.CXX_FastTLS   -> "cxx_fast_tlscc"+   CC.X86_StdCall   -> "cc 64"+   CC.X86_FastCall  -> "cc 65"+   CC.ARM_APCS      -> "cc 66"+   CC.ARM_AAPCS     -> "cc 67"+   CC.ARM_AAPCS_VFP -> "cc 68"+   CC.MSP430_INTR   -> "cc 69"+   CC.X86_ThisCall  -> "cc 70"+   CC.PTX_Kernel    -> "cc 71"+   CC.PTX_Device    -> "cc 72"+   CC.SPIR_FUNC     -> "cc 75"+   CC.SPIR_KERNEL   -> "cc 76"+   CC.Intel_OCL_BI  -> "cc 77"+   CC.X86_64_SysV   -> "cc 78"+   CC.Win64         -> "cc 79"+   CC.X86_Intr      -> "x86_intrcc"+   CC.X86_RegCall   -> "x86_regcallcc"+   CC.X86_VectorCall -> "x86_vectorcallcc"+   CC.AVR_Intr      -> "avr_intrcc"+   CC.AVR_Signal    -> "avr_signalcc"+   CC.AVR_Builtin   -> "cc 86"+   CC.HHVM          -> "hhvmcc"+   CC.HHVM_C        -> "hhvm_ccc"+   CC.AMDGPU_VS     -> "amdgpu_vs"+   CC.AMDGPU_GS     -> "amdgpu_gs"+   CC.AMDGPU_PS     -> "amdgpu_ps"+   CC.AMDGPU_CS     -> "amdgpu_cs"+   CC.AMDGPU_HS     -> "amdgpu_hs"+   CC.AMDGPU_Kernel -> "amdgpu_kernel"+   CC.MSP430_Builtin -> "msp430"++instance Pretty L.Linkage where+    pretty = ppLinkage False++ppLinkage :: Bool -> L.Linkage -> Doc ann+ppLinkage omitExternal = \case+   L.External | omitExternal -> mempty+              | otherwise    -> "external"+   L.Private                 -> "private"+   L.Internal                -> "internal"+   L.ExternWeak              -> "extern_weak"+   L.AvailableExternally     -> "available_externally"+   L.LinkOnce                -> "linkonce"+   L.Weak                    -> "weak"+   L.Common                  -> "common"+   L.Appending               -> "appending"+   L.LinkOnceODR             -> "linkonce_odr"+   L.WeakODR                 -> "weak_odr"++ppInstructionMetadata :: InstructionMetadata -> Doc ann+ppInstructionMetadata meta = commas ["!" <> short x <+> pretty y | (x,y) <- meta]++instance Pretty MetadataNodeID where+  pretty (MetadataNodeID x) = "!" <> pretty ((fromIntegral x) :: Int)++instance Pretty GroupID where+  pretty (GroupID x) = "#" <> pretty ((fromIntegral x) :: Int)++instance Pretty BasicBlock where+  pretty (BasicBlock nm instrs term) =+    label <> P.line <> indent 2 (vcat $ (fmap pretty instrs) ++ [pretty term])+    where+      label = case nm of+        UnName _ -> "; <label>:" <> pretty nm <> ":"+        _ -> pretty nm <> ":"++instance Pretty Terminator where+  pretty = \case+    Br dest meta -> "br" <+> label (pretty dest) <+> ppInstrMeta meta++    Ret val meta -> "ret" <+> maybe "void" ppTyped val <+> ppInstrMeta meta++    CondBr cond tdest fdest meta ->+     "br" <+> ppTyped cond+     `cma` label (pretty tdest)+     `cma` label (pretty fdest)+     <+> ppInstrMeta meta++    Switch {..} -> "switch" <+> ppTyped operand0'+                 `cma` label (pretty defaultDest)+                 <+> brackets (hsep [ ppTyped v `cma` label (pretty l) | (v,l) <- dests ])+                 <+> ppInstrMeta metadata'++    Unreachable {..} -> "unreachable" <+> ppInstrMeta metadata'++    IndirectBr op dests meta -> "indirectbr" <+> ppTyped op `cma`+     brackets (hsep [ label (pretty l) | l <- dests ])+     <+> ppInstrMeta meta++    e @ Invoke {..} ->+     ppInvoke e+     <+> "to" <+> label (pretty returnDest)+     <+> "unwind" <+> label (pretty exceptionDest)+     <+> ppInstrMeta metadata'++    Resume op meta -> "resume "<+> ppTyped op <+> ppInstrMeta meta++    CleanupRet pad dest meta ->+      "cleanupret" <+> "from" <+> pretty pad <+> "unwind" <+> maybe "to caller" (label . pretty) dest+      <+> ppInstrMeta meta++    CatchRet catchPad succ meta ->+      "catchret" <+> "from" <+> pretty catchPad <+> "to" <+> label (pretty succ)+      <+> ppInstrMeta meta++    CatchSwitch {..} ->+      "catchswitch" <+> "within" <+> pretty parentPad' <+>+      brackets (commas (map (label . pretty) (toList catchHandlers))) <+>+      "unwind" <+> "to" <+> maybe "caller" pretty defaultUnwindDest+      <+> ppInstrMeta metadata'++instance Pretty Instruction where+  pretty = \case+    Add {..}    -> ppInstrWithNuwNsw "add" nuw nsw operand0 operand1 metadata+    Sub {..}    -> ppInstrWithNuwNsw "sub" nuw nsw operand0 operand1 metadata+    Mul {..}    -> ppInstrWithNuwNsw "mul" nuw nsw operand0 operand1 metadata+    Shl {..}    -> ppInstrWithNuwNsw "shl" nuw nsw operand0 operand1 metadata+    AShr {..}   -> ppInstrWithExact "ashr" exact operand0 operand1 metadata+    LShr {..}   -> ppInstrWithExact "lshr" exact operand0 operand1 metadata++    And {..}    -> "and"  <+> ppTyped operand0 `cma` pretty operand1 <+> ppInstrMeta metadata+    Or {..}     -> "or"   <+> ppTyped operand0 `cma` pretty operand1 <+> ppInstrMeta metadata+    Xor {..}    -> "xor"  <+> ppTyped operand0 `cma` pretty operand1 <+> ppInstrMeta metadata+    SDiv {..}   -> ppInstrWithExact "sdiv" exact operand0 operand1 metadata+    UDiv {..}   -> ppInstrWithExact "udiv" exact operand0 operand1 metadata+    SRem {..}   -> "srem"  <+> ppTyped operand0 `cma` pretty operand1 <+> ppInstrMeta metadata+    URem {..}   -> "urem"  <+> ppTyped operand0 `cma` pretty operand1 <+> ppInstrMeta metadata++    FAdd {..}   -> "fadd" <+> ppTyped operand0 `cma` pretty operand1 <+> ppInstrMeta metadata+    FSub {..}   -> "fsub" <+> ppTyped operand0 `cma` pretty operand1 <+> ppInstrMeta metadata+    FMul {..}   -> "fmul" <+> ppTyped operand0 `cma` pretty operand1 <+> ppInstrMeta metadata+    FDiv {..}   -> "fdiv" <+> ppTyped operand0 `cma` pretty operand1 <+> ppInstrMeta metadata+    FRem {..}   -> "frem" <+> ppTyped operand0 `cma` pretty operand1 <+> ppInstrMeta metadata+    FCmp {..}   -> "fcmp" <+> pretty fpPredicate <+> ppTyped operand0 `cma` pretty operand1 <+> ppInstrMeta metadata++    Alloca {..} -> "alloca" <+> pretty allocatedType <> num <> ppAlign alignment <+> ppInstrMeta metadata+      where num   = case numElements of Nothing -> mempty+                                        Just o -> "," <+> ppTyped o+    Store {..}  -> "store" <+> ppVolatile volatile <+> ppTyped value `cma` ppTyped address <> ppAlign alignment <+> ppInstrMeta metadata+    Load {..}   -> "load" <+> ppVolatile volatile <+> pretty argTy `cma` ppTyped address <> ppAlign alignment <+> ppInstrMeta metadata+      where PointerType argTy _ = typeOf address+    Phi {..}    -> "phi" <+> pretty type' <+> commas (fmap phiIncoming incomingValues) <+> ppInstrMeta metadata++    ICmp {..}   -> "icmp" <+> pretty iPredicate <+> ppTyped operand0 `cma` pretty operand1 <+> ppInstrMeta metadata++    c@Call {..} -> ppCall c  <+> ppInstrMeta metadata+    Select {..} -> "select" <+> commas [ppTyped condition', ppTyped trueValue, ppTyped falseValue] <+> ppInstrMeta metadata+    SExt {..}   -> "sext" <+> ppTyped operand0 <+> "to" <+> pretty type' <+> ppInstrMeta metadata <+> ppInstrMeta metadata+    ZExt {..}   -> "zext" <+> ppTyped operand0 <+> "to" <+> pretty type' <+> ppInstrMeta metadata <+> ppInstrMeta metadata+    FPExt {..}   -> "fpext" <+> ppTyped operand0 <+> "to" <+> pretty type' <+> ppInstrMeta metadata <+> ppInstrMeta metadata+    Trunc {..}  -> "trunc" <+> ppTyped operand0 <+> "to" <+> pretty type' <+> ppInstrMeta metadata <+> ppInstrMeta metadata+    FPTrunc {..}  -> "fptrunc" <+> ppTyped operand0 <+> "to" <+> pretty type' <+> ppInstrMeta metadata <+> ppInstrMeta metadata++    GetElementPtr {..} -> "getelementptr" <+> bounds inBounds <+> commas (pretty argTy : fmap ppTyped (address:indices)) <+> ppInstrMeta metadata+      where argTy = getElementType $ typeOf address+    ExtractValue {..} -> "extractvalue" <+> commas (ppTyped aggregate : fmap pretty indices') <+> ppInstrMeta metadata++    BitCast {..} -> "bitcast" <+> ppTyped operand0 <+> "to" <+> pretty type' <+> ppInstrMeta metadata+    FPToUI {..} -> "fptoui" <+> ppTyped operand0 <+> "to" <+> pretty type' <+> ppInstrMeta metadata+    FPToSI {..} -> "fptosi" <+> ppTyped operand0 <+> "to" <+> pretty type' <+> ppInstrMeta metadata+    UIToFP {..} -> "uitofp" <+> ppTyped operand0 <+> "to" <+> pretty type' <+> ppInstrMeta metadata+    SIToFP {..} -> "sitofp" <+> ppTyped operand0 <+> "to" <+> pretty type' <+> ppInstrMeta metadata+    PtrToInt {..} -> "ptrtoint" <+> ppTyped operand0 <+> "to" <+> pretty type' <+> ppInstrMeta metadata+    IntToPtr {..} -> "inttoptr" <+> ppTyped operand0 <+> "to" <+> pretty type' <+> ppInstrMeta metadata++    InsertElement {..} -> "insertelement" <+> commas [ppTyped vector, ppTyped element, ppTyped index] <+> ppInstrMeta metadata+    ShuffleVector {..} -> "shufflevector" <+> commas [ppTyped operand0, ppTyped operand1, ppTyped mask] <+> ppInstrMeta metadata+    ExtractElement {..} -> "extractelement" <+> commas [ppTyped vector, ppTyped index] <+> ppInstrMeta metadata+    InsertValue {..} -> "insertvalue" <+> commas (ppTyped aggregate : ppTyped element : fmap pretty indices') <+> ppInstrMeta metadata++    Fence {..} -> "fence" <+> ppAtomicity atomicity <+> ppInstrMeta metadata+    AtomicRMW {..} -> "atomicrmw" <+> ppVolatile volatile <+> pretty rmwOperation <+> ppTyped address `cma` ppTyped value <+> ppAtomicity atomicity  <+> ppInstrMeta metadata+    CmpXchg {..} -> "cmpxchg" <+> ppVolatile volatile <+> ppTyped address `cma` ppTyped expected `cma` ppTyped replacement+      <+> ppAtomicity atomicity <+> pretty failureMemoryOrdering <+> ppInstrMeta metadata++    AddrSpaceCast {..} -> "addrspacecast" <+> ppTyped operand0 <+> "to" <+> pretty type' <+> ppInstrMeta metadata+    VAArg {..} -> "va_arg" <+> ppTyped argList `cma` pretty type' <+> ppInstrMeta metadata++    LandingPad {..} ->+      "landingpad" <+> pretty type' <+> ppBool "cleanup" cleanup <+> ppInstrMeta metadata+      <+> commas (fmap pretty clauses)+    CatchPad {..} -> "catchpad" <+> "within" <+> pretty catchSwitch <+> brackets (commas (map ppTyped args)) <+> ppInstrMeta metadata+    CleanupPad {..} -> "cleanuppad" <+> "within" <+> pretty parentPad <+> brackets (commas (map ppTyped args)) <+> ppInstrMeta metadata++    where+      bounds True = "inbounds"+      bounds False = mempty++      ppInstrWithNuwNsw :: Doc ann -> Bool -> Bool -> Operand -> Operand -> InstructionMetadata -> Doc ann +      ppInstrWithNuwNsw name nuw nsw op0 op1 metadata =+        name+        <+> ppBool "nuw" nuw+        <+> ppBool "nsw" nsw+        <+> ppTyped op0+        `cma` pretty op1+        <+> ppInstrMeta metadata++      ppInstrWithExact :: Doc ann -> Bool -> Operand -> Operand -> InstructionMetadata -> Doc ann+      ppInstrWithExact name exact op0 op1 metadata =+        name+        <+> ppBool "exact" exact+        <+> ppTyped op0+        `cma` pretty op1+        <+> ppInstrMeta metadata++instance Pretty CallableOperand where+  pretty (Left asm) = error "CallableOperand"+  pretty (Right op) = pretty op++instance Pretty LandingPadClause where+  pretty = \case+    Catch c  -> "catch" <+> ppTyped c+    Filter c -> "filter" <+> ppTyped c++-- instance Pretty [Either GroupID FunctionAttribute] where+--   pretty x = hsep $ fmap pretty x++instance Pretty (Either GroupID FunctionAttribute) where+  pretty (Left gid) = pretty gid+  pretty (Right fattr) = pretty fattr++instance Pretty Operand where+  pretty (LocalReference _ nm) = local' (pretty nm)+  pretty (ConstantOperand con) = pretty con+  pretty (MetadataOperand mdata) = pretty mdata++instance Pretty Metadata where+  pretty (MDString str) = "!" <> dquotes (pretty (decodeShortUtf8 str))+  pretty (MDNode node) = pretty node+  pretty (MDValue operand) = ppTyped operand++ppDINode :: [Char] -> [([Char], Maybe (Doc ann))] -> Doc ann+ppDINode name attrs = "!" <> pretty name <> parens (commas (mapMaybe (\(k, mayV) -> fmap (\v -> pretty k <> ":" <+> v) mayV) attrs))++ppDIArray :: [Doc ann] -> Maybe (Doc ann)+ppDIArray [] = Nothing+ppDIArray xs = Just ("!" <> braces (commas xs))++instance Pretty a => Pretty (MDRef a) where+  pretty (MDInline a) = pretty a+  pretty (MDRef ref) = pretty ref++instance Pretty MDNode where+  pretty (MDTuple xs) = "!" <> braces (commas (map ppMetadata xs))+  pretty (DIExpression e) = pretty e+  pretty (DIGlobalVariableExpression e) = pretty e+  pretty (DILocation l) = pretty l+  pretty (DIMacroNode m) = pretty m+  pretty (DINode n) = pretty n++instance Pretty DIExpression where+  pretty (Expression os) = "!DIExpression" <> parens (commas (concatMap ppDWOp os))++ppDWOp :: DWOp -> [Doc ann]+ppDWOp o = case o of+  DwOpFragment DW_OP_LLVM_Fragment {..} -> ["DW_OP_LLVM_fragment", pretty offset, pretty size]+  DW_OP_StackValue -> ["DW_OP_stack_value"]+  DW_OP_Swap -> ["DW_OP_swap"]+  DW_OP_ConstU c -> ["DW_OP_constu", pretty c]+  DW_OP_PlusUConst c -> ["DW_OP_plus_uconst", pretty c]+  DW_OP_Plus -> ["DW_OP_plus"]+  DW_OP_Minus -> ["DW_OP_minus"]+  DW_OP_Mul -> ["DW_OP_mul"]+  DW_OP_Deref -> ["DW_OP_deref"]+  DW_OP_XDeref -> ["DW_OP_xderef"]++instance Pretty DIGlobalVariableExpression where+  pretty e = ppDINode "DIGlobalVariableExpression"+    [ ("var", Just (pretty (var e)))+    , ("expr", Just (pretty (expr e)))+    ]++instance Pretty DILocation where+  pretty (Location line col scope) =+    ppDINode "DILocation" [("line", Just (pretty line)), ("column", Just (pretty col)), ("scope", Just (pretty scope))]++instance Pretty DIMacroNode where+  pretty DIMacro {..} = ppDINode "DIMacro"+    [("type", Just (pretty info)), ("line", Just (pretty line)), ("name", ppSbs name), ("value", ppSbs value)]+  pretty DIMacroFile {..} = ppDINode "DIMacroFile"+    [ ("line", Just (pretty line))+    , ("file", Just (pretty file))+    , ("nodes", ppDIArray (map pretty elements))+    ]++instance Pretty DIMacroInfo where+  pretty Define = "DW_MACINFO_define"+  pretty Undef = "DW_MACINFO_undef"++instance Pretty DINode where+  pretty (DIEnumerator e) = pretty e+  pretty (DIImportedEntity e) = pretty e+  pretty (DIObjCProperty p) = pretty p+  pretty (DIScope s) = pretty s+  pretty (DISubrange r) = pretty r+  pretty (DITemplateParameter p) = pretty p+  pretty (DIVariable v) = pretty v++instance Pretty DILocalScope where+  pretty (DILexicalBlockBase b) = pretty b+  pretty (DISubprogram p) = pretty p++instance Pretty DIEnumerator where+  pretty (Enumerator val name) = ppDINode "DIEnumerator" [("name", ppSbs name), ("value", Just (pretty val))]++instance Pretty DIImportedEntity where+  pretty ImportedEntity {..} = ppDINode "DIImportedEntity"+    [ ("tag", Just (pretty tag))+    , ("scope", Just (pretty scope))+    , ("name", ppSbs name)+    , ("entity", fmap pretty entity)+    , ("file", fmap pretty file)+    , ("line", Just (pretty line))+    ]++instance Pretty ImportedEntityTag where+  pretty ImportedModule = "DW_TAG_imported_module"+  pretty ImportedDeclaration = "DW_TAG_imported_declaration"++instance Pretty DIObjCProperty where+  pretty ObjCProperty {..} = ppDINode "DIObjCProperty"+    [ ("name", ppSbs name)+    , ("file", fmap pretty file)+    , ("line", Just (pretty line))+    , ("setter", ppSbs getterName)+    , ("getter", ppSbs setterName)+    , ("attributes", Just (pretty attributes))+    , ("type", fmap pretty type')+    ]++instance Pretty DIScope where+  pretty (DICompileUnit cu) = pretty cu+  pretty (DIFile f) = pretty f+  pretty (DILocalScope s) = pretty s+  pretty (DIModule m) = pretty m+  pretty (DINamespace ns) = pretty ns+  pretty (DIType t) = pretty t++instance Pretty DISubrange where+  pretty Subrange {..} = ppDINode "DISubrange" [("count", Just (pretty count)), ("lowerBound", Just (pretty lowerBound))]++instance Pretty DITemplateParameter where+  pretty DITemplateTypeParameter {..} = ppDINode "DITemplateTypeParameter"+    [ ("name", ppSbs name), ("type", Just (pretty type')) ]+  pretty DITemplateValueParameter {..} = ppDINode "DITemplateValueParameter"+   [ ("tag", ppTemplateValueParameterTag tag)+   , ("name", ppSbs name)+   , ("type", Just (pretty type'))+   , ("value", Just (pretty value))+   ]++ppTemplateValueParameterTag :: TemplateValueParameterTag -> Maybe (Doc ann)+ppTemplateValueParameterTag TemplateValueParameter = Nothing+ppTemplateValueParameterTag GNUTemplateTemplateParam = Just "DW_TAG_GNU_template_template_param"+ppTemplateValueParameterTag GNUTemplateParameterPack = Just "DW_TAG_GNU_template_parameter_pack"++instance Pretty DIVariable where+  pretty (DIGlobalVariable v) = pretty v+  pretty (DILocalVariable v) = pretty v++instance Pretty DICompileUnit where+  pretty cu@CompileUnit {..} = "distinct" <+> ppDINode "DICompileUnit"+    [ ("language", Just (pretty language))+    , ("file", Just (pretty file))+    , ("producer", ppSbs producer)+    , ("isOptimized", Just (ppBoolean optimized))+    , ("flags", ppSbs flags)+    , ("runtimeVersion", Just (pretty runtimeVersion))+    , ("splitDebugFileName", ppSbs splitDebugFileName)+    , ("emissionKind", Just (pretty emissionKind))+    , ("enums", ppDIArray (map pretty enums))+    , ("retainedTypes", ppDIArray (map ppEither retainedTypes))+    , ("globals", ppDIArray (map pretty globals))+    , ("imports", ppDIArray (map pretty imports))+    , ("macros", ppDIArray (map pretty macros))+    , ("dwoId", Just (pretty dWOId))+    , ("splitDebugInlining", Just (ppBoolean splitDebugInlining))+    , ("debugInfoForProfiling", Just (ppBoolean debugInfoForProfiling))+    , ("gnuPubnames", Just (ppBoolean gnuPubnames))+    ]++instance Pretty DebugEmissionKind where+  pretty NoDebug = "NoDebug"+  pretty FullDebug = "FullDebug"+  pretty LineTablesOnly = "LineTablesOnly"++instance Pretty DIFile where+  pretty (File {..}) = ppDINode "DIFile" $+    [ ("filename", Just (dquotes (pretty filename)))+    , ("directory", Just (dquotes (pretty directory)))+    , ("checksum", ppSbs checksum)+    , ("checksumkind", Just (pretty checksumKind))+    ]++instance Pretty DIModule where+  pretty O.Module {..} = ppDINode "DIModule"+    [ ("scope", Just (maybe "null" pretty scope))+    , ("name", ppSbs name)+    , ("configMacros", ppSbs configurationMacros)+    , ("includePath", ppSbs includePath)+    , ("isysroot", ppSbs isysRoot)+    ]++instance Pretty DINamespace where+  pretty Namespace {..} = ppDINode "DINamespace"+    [ ("name", ppSbs name)+    , ("scope", Just (maybe "null" pretty scope))+    , ("exportSymbols", Just (ppBoolean exportSymbols))+    ]++instance Pretty DIType where+  pretty (DIBasicType t) = pretty t+  pretty (DICompositeType t) = pretty t+  pretty (DIDerivedType t) = pretty t+  pretty (DISubroutineType t) = pretty t++instance Pretty DILexicalBlockBase where+  pretty DILexicalBlock {..} = ppDINode "DILexicalBlock"+    [ ("scope", Just (pretty scope))+    , ("file", fmap pretty file)+    , ("line", Just (pretty line))+    , ("column", Just (pretty column))+    ]+  pretty DILexicalBlockFile {..} = ppDINode "DILexicalBlockFile"+    [ ("scope", Just (pretty scope)), ("file", fmap pretty file), ("discriminator", Just (pretty discriminator)) ]++ppSbs :: BS.ShortByteString -> Maybe (Doc ann)+ppSbs s+  | SBF.null s = Nothing+  | otherwise = Just (dquotes (pretty s))++instance Pretty DISubprogram where+  pretty Subprogram {..} = ppMaybe (if definition then Just ("distinct " :: [Char]) else Nothing) <>+   ppDINode "DISubprogram"+   [ ("name", ppSbs name)+   , ("linkageName", ppSbs linkageName)+   , ("scope", fmap pretty scope)+   , ("file", fmap pretty file)+   , ("line", Just (pretty line))+   , ("type", fmap pretty type')+   , ("isLocal", Just (ppBoolean localToUnit))+   , ("isDefinition", Just (ppBoolean definition))+   , ("scopeLine", Just (pretty scopeLine))+   , ("containingType", fmap pretty containingType)+   , ("virtuality", ppVirtuality virtuality)+   , ("virtualIndex", Just (pretty virtualityIndex))+   , ("thisAdjustment", Just (pretty thisAdjustment))+   , ("flags", ppDIFlags flags)+   , ("isOptimized", Just (ppBoolean optimized))+   , ("unit", fmap pretty unit)+   , ("templateParams", ppDIArray (map pretty templateParams))+   , ("declaration", fmap pretty declaration)+   , ("variables", ppDIArray (map pretty variables))+   , ("thrownTypes", ppDIArray (map pretty thrownTypes))+   ]++ppVirtuality :: Virtuality -> Maybe (Doc ann)+ppVirtuality NoVirtuality = Nothing+ppVirtuality Virtual = Just "DW_VIRTUALITY_virtual"+ppVirtuality PureVirtual = Just "DW_VIRTUALITY_pure_virtual"++instance Pretty ChecksumKind where+  pretty None = "CSK_None"+  pretty MD5 = "CSK_MD5"+  pretty SHA1 = "CSK_SHA1"++instance Pretty DIBasicType where+  pretty (BasicType {..}) = ppDINode "DIBasicType"+    [ ("tag", Just (pretty tag))+    , ("name", ppSbs name)+    , ("size", Just (pretty sizeInBits))+    , ("align", Just (pretty alignInBits))+    , ("encoding", fmap pretty encoding)+    ]++instance Pretty BasicTypeTag where+  pretty BaseType = "DW_TAG_base_type"+  pretty UnspecifiedType = "DW_TAG_unspecified_type"++instance Pretty Encoding where+  pretty e = case e of+    AddressEncoding -> "DW_ATE_address"+    BooleanEncoding -> "DW_ATE_boolean"+    FloatEncoding -> "DW_ATE_float"+    SignedEncoding -> "DW_ATE_signed"+    SignedCharEncoding -> "DW_ATE_signed_char"+    UnsignedEncoding -> "DW_ATE_unsigned"+    UnsignedCharEncoding -> "DW_ATE_unsigned_char"++ppDIFlags :: [DIFlag] -> Maybe (Doc ann)+ppDIFlags [] = Nothing+ppDIFlags flags = Just (hsep (punctuate (pretty '|') (map pretty flags)))++instance Pretty DIFlag where+  pretty flag = "DIFlag" <> fromString (flagName flag)+    where+      flagName (Accessibility f) = show f+      flagName (InheritanceFlag f) = show f+      flagName VirtualFlag = "Virtual"+      flagName f = show f+++ppEither :: (Pretty a, Pretty b) => MDRef (Either a b) -> Doc ann+ppEither (MDRef r) = pretty r+ppEither (MDInline e) = either pretty pretty e++instance Pretty DICompositeType where+  pretty DIArrayType {..} = ppDINode "DICompositeType"+    [ ("tag", Just "DW_TAG_array_type")+    , ("elements", ppDIArray (map pretty subscripts))+    , ("baseType", fmap pretty elementTy)+    , ("size", Just (pretty sizeInBits))+    , ("align", Just (pretty alignInBits))+    , ("flags", ppDIFlags flags)+    ]+  pretty DIClassType {..} = ppDINode "DICompositeType"+    [ ("tag", Just "DW_TAG_class_type")+    , ("scope", fmap pretty scope)+    , ("name", ppSbs name)+    , ("file", fmap pretty file)+    , ("line", Just (pretty line))+    , ("flags", ppDIFlags flags)+    , ("baseType", fmap pretty derivedFrom)+    , ("elements", ppDIArray (map ppEither elements))+    , ("vtableHolder", fmap pretty vtableHolder)+    , ("templateParams", ppDIArray (map pretty templateParams))+    , ("identifier", ppSbs identifier)+    , ("size", Just (pretty sizeInBits))+    , ("align", Just (pretty alignInBits))+    ]+  pretty DIEnumerationType {..} = ppDINode "DICompositeType"+    [ ("tag", Just "DW_TAG_enumeration_type")+    , ("name", ppSbs name)+    , ("file", fmap pretty file)+    , ("line", Just (pretty line))+    , ("size", Just (pretty sizeInBits))+    , ("align", Just (pretty alignInBits))+    , ("elements", Just ("!" <> braces (commas (map pretty values))))+    , ("scope", fmap pretty scope)+    , ("identifier", ppSbs identifier)+    , ("baseType", fmap pretty baseType)+    ]+  pretty DIStructureType {..} = ppDINode "DICompositeType"+    [ ("tag", Just "DW_TAG_structure_type")+    , ("scope", fmap pretty scope)+    , ("name", ppSbs name)+    , ("file", fmap pretty file)+    , ("line", Just (pretty line))+    , ("flags", ppDIFlags flags)+    , ("baseType", fmap pretty derivedFrom)+    , ("elements", ppDIArray (map ppEither elements))+    , ("runtimeLang", Just (pretty runtimeLang))+    , ("vtableHolder", fmap pretty vtableHolder)+    , ("identifier", ppSbs identifier)+    , ("size", Just (pretty sizeInBits))+    , ("align", Just (pretty alignInBits))+    ]+  pretty DIUnionType {..} = ppDINode "DICompositeType"+    [ ("tag", Just "DW_TAG_union_type")+    , ("name", ppSbs name)+    , ("file", fmap pretty file)+    , ("line", Just (pretty line))+    , ("flags", ppDIFlags flags)+    , ("elements", ppDIArray (map ppEither elements))+    , ("runtimeLang", Just (pretty runtimeLang))+    , ("identifier", ppSbs identifier)+    , ("size", Just (pretty sizeInBits))+    , ("align", Just (pretty alignInBits))+    ]++instance Pretty DIDerivedType where+  pretty DerivedType {..} = ppDINode "DIDerivedType"+    [ ("tag", Just (pretty tag))+    , ("name", ppSbs name)+    , ("file", fmap pretty file)+    , ("line", Just (pretty line))+    , ("scope", fmap pretty scope)+    , ("baseType", Just (pretty baseType))+    , ("size", Just (pretty sizeInBits))+    , ("align", Just (pretty alignInBits))+    , ("offset", Just (pretty offsetInBits))+    , ("flags", ppDIFlags flags)+    , ("dwarfAddressSpace", fmap pretty addressSpace)+    ]++instance Pretty DerivedTypeTag where+  pretty t =+    case t of+      Typedef -> "DW_TAG_typedef"+      O.PointerType -> "DW_TAG_pointer_type"+      PtrToMemberType -> "DW_TAG_ptr_to_member_type"+      ReferenceType -> "DW_TAG_reference_type"+      RValueReferenceType -> "DW_TAG_rvalue_reference_type"+      ConstType -> "DW_TAG_const_type"+      VolatileType -> "DW_TAG_volatile_type"+      RestrictType -> "DW_TAG_restrict_type"+      AtomicType -> "DW_TAG_atomic_type"+      Member -> "DW_TAG_member"+      Inheritance -> "DW_TAG_inheritance"+      Friend -> "DW_TAG_friend"++instance Pretty DISubroutineType where+  pretty SubroutineType {..} = ppDINode "DISubroutineType"+    [ ("flags", ppDIFlags flags)+    , ("cc", Just (pretty cc))+    , ("types", Just ("!" <> braces (commas (map ppTy typeArray))))+    ]+    where ppTy Nothing = "null"+          ppTy (Just t) = pretty t++instance Pretty DIGlobalVariable where+  pretty O.GlobalVariable {..} = ppDINode "DIGlobalVariable"+    [ ("name", ppSbs name)+    , ("scope", fmap pretty scope)+    , ("linkageName", ppSbs linkageName)+    , ("file", fmap pretty file)+    , ("line", Just (pretty line))+    , ("type", fmap pretty type')+    , ("isLocal", Just (ppBoolean local))+    , ("isDefinition", Just (ppBoolean definition))+    , ("declaration", fmap pretty staticDataMemberDeclaration)+    , ("align", Just (pretty alignInBits))+    ]++instance Pretty DILocalVariable where+  pretty LocalVariable {..} = ppDINode "DILocalVariable"+    [ ("name", ppSbs name)+    , ("scope", Just (pretty scope))+    , ("file", fmap pretty file)+    , ("line", Just (pretty line))+    , ("type", fmap pretty type')+    , ("flags", ppDIFlags flags)+    , ("arg", Just (pretty arg))+    , ("align", Just (pretty alignInBits))+    ]++instance Pretty C.Constant where+  pretty (C.Int width val) = pretty val+  pretty (C.Float (F.Double val))      =+    if specialFP val+      then "0x" <> (pretty . pack) (showHex (doubleToWord val) "")+      else pretty $ pack $ printf "%6.6e" val+  pretty (C.Float (F.Single val))      =+    if specialFP val+      then "0x" <> (pretty . pack) (showHex (floatToWord val) "")+      else pretty $ pack $ printf "%6.6e" val+  pretty (C.Float (F.Half val))        = pretty $ pack $ printf "%6.6e" val+  pretty (C.Float (F.Quadruple val _)) = pretty $ pack $ printf "%6.6e" val+  pretty (C.Float (F.X86_FP80 val _))  = pretty $ pack $ printf "%6.6e" val+  pretty (C.Float (F.PPC_FP128 val _)) = pretty $ pack $ printf "%6.6e" val++  pretty (C.GlobalReference ty nm) = "@" <> pretty nm+  pretty (C.Vector args) = "<" <+> commas (fmap ppTyped args) <+> ">"++  pretty (C.Add {..})    = "add"  <+> ppTyped operand0 `cma` pretty operand1+  pretty (C.Sub {..})    = "sub"  <+> ppTyped operand0 `cma` pretty operand1+  pretty (C.Mul {..})    = "mul"  <+> ppTyped operand0 `cma` pretty operand1+  pretty (C.Shl {..})    = "shl"  <+> ppTyped operand0 `cma` pretty operand1+  pretty (C.AShr {..})   = "ashr" <+> ppTyped operand0 `cma` pretty operand1+  pretty (C.LShr {..})   = "lshr" <+> ppTyped operand0 `cma` pretty operand1+  pretty (C.And {..})    = "and"  <+> ppTyped operand0 `cma` pretty operand1+  pretty (C.Or {..})     = "or"   <+> ppTyped operand0 `cma` pretty operand1+  pretty (C.Xor {..})    = "xor"  <+> ppTyped operand0 `cma` pretty operand1+  pretty (C.SDiv {..})   = "sdiv"  <+> ppTyped operand0 `cma` pretty operand1+  pretty (C.UDiv {..})   = "udiv"  <+> ppTyped operand0 `cma` pretty operand1+  pretty (C.SRem {..})   = "srem"  <+> ppTyped operand0 `cma` pretty operand1+  pretty (C.URem {..})   = "urem"  <+> ppTyped operand0 `cma` pretty operand1++  pretty (C.FAdd {..})   = "fadd" <+> ppTyped operand0 `cma` pretty operand1+  pretty (C.FSub {..})   = "fsub" <+> ppTyped operand0 `cma` pretty operand1+  pretty (C.FMul {..})   = "fmul" <+> ppTyped operand0 `cma` pretty operand1+  pretty (C.FDiv {..})   = "fdiv" <+> ppTyped operand0 `cma` pretty operand1+  pretty (C.FRem {..})   = "frem" <+> ppTyped operand0 `cma` pretty operand1+  pretty (C.FCmp {..})   = "fcmp" <+> pretty fpPredicate <+> ppTyped operand0 `cma` pretty operand1+  pretty C.ICmp {..}     = "icmp" <+> pretty iPredicate <+> ppTyped operand0 `cma` pretty operand1++  pretty (C.Select {..})  = "select" <+> commas [ppTyped condition', ppTyped trueValue, ppTyped falseValue]+  pretty (C.SExt {..})    = "sext" <+> ppTyped operand0 <+> "to" <+> pretty type'+  pretty (C.ZExt {..})    = "zext" <+> ppTyped operand0 <+> "to" <+> pretty type'+  pretty (C.FPExt {..})   = "fpext" <+> ppTyped operand0 <+> "to" <+> pretty type'+  pretty (C.Trunc {..})   = "trunc" <+> ppTyped operand0 <+> "to" <+> pretty type'+  pretty (C.FPTrunc {..}) = "fptrunc" <+> ppTyped operand0 <+> "to" <+> pretty type'++  pretty C.FPToUI {..} = "fptoui" <+> ppTyped operand0 <+> "to" <+> pretty type'+  pretty C.FPToSI {..} = "fptosi" <+> ppTyped operand0 <+> "to" <+> pretty type'+  pretty C.UIToFP {..} = "uitofp" <+> ppTyped operand0 <+> "to" <+> pretty type'+  pretty C.SIToFP {..} = "sitofp" <+> ppTyped operand0 <+> "to" <+> pretty type'++  pretty (C.Struct _ packed elems) =+    let struct = spacedbraces $ commas $ fmap ppTyped elems+    in if packed+         then angleBrackets struct+         else struct++  pretty (C.Null constantType) = ppNullInitializer constantType++#if MIN_VERSION_llvm_hs_pure(5,1,3)+  pretty (C.AggregateZero constantType) = "zeroinitializer"+#endif++  pretty (C.Undef {}) = "undef"+  pretty (C.TokenNone {}) = "none"+  pretty (C.BlockAddress fn blk) = "blockaddress" <> parens (commas (fmap pretty [fn, blk]))++  pretty C.Array {..}+    | memberType == (IntegerType 8) = "c" <> (dquotes $ hcat [ppIntAsChar val | C.Int _ val <- memberValues])+    | otherwise = brackets $ commas $ fmap ppTyped memberValues++  pretty C.GetElementPtr {..} = "getelementptr" <+> bounds inBounds <+> parens (commas (pretty argTy : fmap ppTyped (address:indices)))+    where+      PointerType argTy _ = typeOf address+      bounds True = "inbounds"+      bounds False = mempty++  pretty C.BitCast {..} = "bitcast" <+> parens (ppTyped operand0 <+> "to" <+> pretty type')+  pretty C.PtrToInt {..} = "ptrtoint" <+> parens (ppTyped operand0 <+> "to" <+> pretty type')+  pretty C.IntToPtr {..} = "inttoptr" <+> parens (ppTyped operand0 <+> "to" <+> pretty type')+  pretty C.AddrSpaceCast {..} = "addrspacecast" <+> parens (ppTyped operand0 <+> "to" <+> pretty type')+  pretty _ = error "Non-function argument. (Malformed AST)"++instance Pretty a => Pretty (Named a) where+  pretty (nm := a) = "%" <> pretty nm <+> "=" <+> pretty a+  pretty (Do a) = pretty a++instance Pretty Module where+  pretty Module {..} =+    let header = printf "; ModuleID = '%s'" (unShort moduleName) in+    let target = case moduleTargetTriple of+                      Nothing -> mempty+                      Just target -> "target triple =" <+> dquotes (short target) in+    let layout = case moduleDataLayout of+                      Nothing     -> mempty+                      Just layout -> "target datalayout =" <+> dquotes (pretty layout) in+    hlinecat (fromString header : (layout <> softline <> target) : (fmap pretty moduleDefinitions))++instance Pretty FP.FloatingPointPredicate where+  pretty op = case op of+   FP.False -> "false"+   FP.OEQ   -> "oeq"+   FP.OGT   -> "ogt"+   FP.OGE   -> "oge"+   FP.OLT   -> "olt"+   FP.OLE   -> "ole"+   FP.ONE   -> "one"+   FP.ORD   -> "ord"+   FP.UEQ   -> "ueq"+   FP.UGT   -> "ugt"+   FP.UGE   -> "uge"+   FP.ULT   -> "ult"+   FP.ULE   -> "ule"+   FP.UNE   -> "une"+   FP.UNO   -> "uno"+   FP.True  -> "true"++instance Pretty IP.IntegerPredicate where+  pretty op = case op of+   IP.EQ  -> "eq"+   IP.NE  -> "ne"+   IP.UGT -> "ugt"+   IP.UGE -> "uge"+   IP.ULT -> "ult"+   IP.ULE -> "ule"+   IP.SGT -> "sgt"+   IP.SGE -> "sge"+   IP.SLT -> "slt"+   IP.SLE -> "sle"++-- instance Pretty Atomicity where+--   pretty (scope, order) =+--     pretty scope <+> pretty order++ppAtomicity :: Atomicity -> Doc ann+ppAtomicity (scope, order) = pretty scope <+> pretty order++instance Pretty SynchronizationScope where+  pretty = \case+    SingleThread -> "syncscope(\"singlethread\")"+    System -> mempty++instance Pretty MemoryOrdering where+  pretty = \case+    Unordered              -> "unordered"+    Monotonic              -> "monotonic"+    Acquire                -> "acquire"+    Release                -> "release"+    AcquireRelease         -> "acq_rel"+    SequentiallyConsistent -> "seq_cst"++instance Pretty RMW.RMWOperation where+  pretty = \case+    RMW.Xchg -> "xchg"+    RMW.Add -> "add"+    RMW.Sub -> "sub"+    RMW.And -> "and"+    RMW.Nand -> "nand"+    RMW.Or -> "or"+    RMW.Xor -> "xor"+    RMW.Max -> "max"+    RMW.Min -> "min"+    RMW.UMax -> "umax"+    RMW.UMin -> "umin"++instance Pretty DataLayout where+  pretty x = pretty (BL.unpack (dataLayoutToString x))++-- -------------------------------------------------------------------------------+-- -- Special Case Hacks+-- -------------------------------------------------------------------------------++escape :: Char -> Doc ann+escape '"'  = pretty ("\\22" :: String)+escape '\\' = pretty ("\\\\" :: String)+escape c    = if isAscii c && not (isControl c)+              then pretty c+              else pretty ("\\" :: String) <> hex c+    where+        hex :: Char -> Doc ann+        hex = pad0 . ($ []) . showHex . ord+        pad0 :: String -> Doc ann+        pad0 [] = "00"+        pad0 [x] = "0" <> pretty x+        pad0 xs = pretty (pack xs)++ppVolatile :: Bool -> Doc ann+ppVolatile True = "volatile"+ppVolatile False = mempty++ppIntAsChar :: Integral a => a -> Doc ann+ppIntAsChar = escape . chr . fromIntegral++ppAlign :: Word32 -> Doc ann+ppAlign x | x == 0    = mempty+          | otherwise = ", align" <+> pretty x++-- print an operand and its type+ppTyped :: (Pretty a, Typed a) => a -> Doc ann+ppTyped a = pretty (typeOf a) <+> pretty a++ppCommaTyped :: (Pretty a, Typed a) => a -> Doc ann+ppCommaTyped a = pretty (typeOf a) `cma` pretty a++phiIncoming :: (Operand, Name) -> Doc ann+phiIncoming (op, nm) = brackets (pretty op `cma` (local' (pretty nm)))++ppParams :: (a -> Doc ann) -> ([a], Bool) -> Doc ann+ppParams ppParam (ps, varrg) = parens . commas $ fmap ppParam ps ++ vargs+    where+        vargs = if varrg then ["..."] else []++ppFunctionArgumentTypes :: Type -> Doc ann+ppFunctionArgumentTypes FunctionType {..} = ppParams pretty (argumentTypes, isVarArg)+ppFunctionArgumentTypes _ = error "Non-function argument. (Malformed AST)"++ppNullInitializer :: Type -> Doc ann+ppNullInitializer PointerType {..} = "zeroinitializer"+ppNullInitializer StructureType {..} = "zeroinitializer"+ppNullInitializer FunctionType {..} = "zeroinitializer"+ppNullInitializer ArrayType {..} = "zeroinitializer"+ppNullInitializer _ = error "Non-pointer argument. (Malformed AST)"++ppCall :: Instruction -> Doc ann+ppCall Call { function = Right f,..}+  = tail <+> "call" <+> pretty callingConvention <+> ppReturnAttributes returnAttributes <+> pretty resultType <+> ftype+    <+> pretty f <> parens (commas $ fmap ppArguments arguments) <+> ppFunctionAttributes functionAttributes+    where+      (functionType@FunctionType {..}) = referencedType (typeOf f)+      ftype = if isVarArg+              then ppFunctionArgumentTypes functionType+              else mempty+      referencedType (PointerType t _) = referencedType t+      referencedType t                 = t++      tail = case tailCallKind of+        Just Tail -> "tail"+        Just MustTail -> "musttail"+        Just NoTail -> "notail"+        Nothing -> mempty+ppCall Call { function = Left (IA.InlineAssembly {..}), ..}+  = tail <+> "call" <+> pretty callingConvention <+> ppReturnAttributes returnAttributes <+> pretty type'+    <+> "asm" <+> sideeffect' <+> align' <+> dialect' <+> dquotes (pretty (pack (BL.unpack assembly))) <> ","+    <+> dquotes (pretty constraints) <> parens (commas $ fmap ppArguments arguments) <+> ppFunctionAttributes functionAttributes+    where+      tail = case tailCallKind of+        Just Tail -> "tail"+        Just MustTail -> "musttail"+        Just NoTail -> "notail"+        Nothing -> mempty+      -- If multiple keywords appear the ‘sideeffect‘ keyword must come first,+      -- the ‘alignstack‘ keyword second and the ‘inteldialect‘ keyword last.+      sideeffect' = if hasSideEffects then "sideeffect" else ""+      align' = if alignStack then "alignstack" else ""+      -- ATTDialect is assumed if not specified+      dialect' = case dialect of IA.ATTDialect -> ""; IA.IntelDialect -> "inteldialect"+ppCall x = error "Non-callable argument. (Malformed AST)"++ppReturnAttributes :: [ParameterAttribute] -> Doc ann+ppReturnAttributes pas = hsep $ fmap pretty pas++-- Differs from Call in record name conventions only so needs a seperate almost+-- identical function. :(+ppInvoke :: Terminator -> Doc ann+ppInvoke Invoke { function' = Right f,..}+  = "invoke" <+> pretty callingConvention' <+> pretty resultType <+> ftype+    <+> pretty f <> parens (commas $ fmap ppArguments arguments') <+> ppFunctionAttributes functionAttributes'+    where+      (functionType@FunctionType {..}) = referencedType (typeOf f)+      ftype = if isVarArg+              then ppFunctionArgumentTypes functionType+              else mempty+      referencedType (PointerType t _) = referencedType t+      referencedType t                 = t+ppInvoke x = error "Non-callable argument. (Malformed AST)"++ppSingleBlock :: BasicBlock -> Doc ann+ppSingleBlock (BasicBlock nm instrs term) = (vcat $ (fmap pretty instrs) ++ [pretty term])++-- According to <https://stackoverflow.com/a/7002812/3877993> this is+-- the best way to cast floats to words.++cast :: (MArray (STUArray s) a (ST s),+         MArray (STUArray s) b (ST s)) => a -> ST s b+cast x = newArray (0 :: Int, 0) x >>= castSTUArray >>= flip readArray 0++doubleToWord :: Double -> Word64+doubleToWord x = runST (cast x)++floatToWord :: Float -> Word32+floatToWord x = runST (cast x)++specialFP :: RealFloat a => a -> Bool+specialFP f = isNaN f || f == 1 / 0 || f == - 1 / 0++ppInstrMeta :: InstructionMetadata -> Doc ann+ppInstrMeta [] = mempty+ppInstrMeta xs = "," <> ppInstructionMetadata xs++ppLayoutOptions :: LayoutOptions+ppLayoutOptions = LayoutOptions (AvailablePerLine 100 0.5)++-- -------------------------------------------------------------------------------+-- -- Toplevel+-- -------------------------------------------------------------------------------++-- | Pretty print a LLVM module+ppllvm :: Module -> Text+ppllvm = renderLazy . layoutPretty ppLayoutOptions . pretty ++-- | Pretty print a printable LLVM expression+ppll :: Pretty a => a -> Text+ppll = renderLazy . layoutPretty ppLayoutOptions . pretty