content: {-# LANGUAGE OverloadedStrings #-}
  -- | This module and descendants define AST data types to represent LLVM code.
  -- Note that these types are designed for fidelity rather than convenience - if the truth
  -- of what LLVM supports is less than pretty, so be it.
  module LLVM.AST (
    Module(..), defaultModule,
    Definition(..),
    Global(GlobalVariable, GlobalAlias, Function),
          globalVariableDefaults,
          globalAliasDefaults,
          functionDefaults,
    UnnamedAddr(..),
    Parameter(..),
    BasicBlock(..),
    Operand(..),
    CallableOperand,
    Metadata(..),
    MetadataNodeID(..),
    MDRef(..),
    MDNode(..),
    module LLVM.AST.Instruction,
    module LLVM.AST.Name,
    module LLVM.AST.Type
    -- * Overview
    -- $overview
  
    -- * Constructing the AST for an LLVM module
    -- $moduleconstruction
    ) where
  
  import LLVM.Prelude
  
  import LLVM.AST.Name
  import LLVM.AST.Type (Type(..), FloatingPointType(..))
  import LLVM.AST.Global
  import LLVM.AST.Operand hiding (Module)
  import LLVM.AST.Instruction
  import LLVM.AST.DataLayout
  import qualified LLVM.AST.Attribute as A
  import qualified LLVM.AST.COMDAT as COMDAT
  
  {- $overview
  
  @llvm-hs-pure@ defines the Haskell AST for representing an LLVM
  `Module`. For interacting with the LLVM C/C++ libraries and an
  overview of the various libraries in the @llvm-hs@ ecosystem, take a
  look at the docs in the @LLVM@ module in @llvm-hs@.
  
  In addition to constructing the LLVM AST manually, there is also a
  monadic IRBuilder interface in `LLVM.IRBuilder`. The IRBuilder will
  take care of generating fresh names automatically and generally
  reduces the verbosity of using the AST directly. Using
  @RecursiveDo/mdo@, it is also capable of handling forward references
  automatically.
  -}
  
  -- | Any thing which can be at the top level of a 'Module'
  data Definition
    = GlobalDefinition Global
    | TypeDefinition Name (Maybe Type)
    | MetadataNodeDefinition MetadataNodeID MDNode
    | NamedMetadataDefinition ShortByteString [MetadataNodeID]
    | ModuleInlineAssembly ByteString
    | FunctionAttributes A.GroupID [A.FunctionAttribute]
    | COMDAT ShortByteString COMDAT.SelectionKind
      deriving (Eq, Read, Show, Typeable, Data, Generic)
  
  -- | <http://llvm.org/docs/LangRef.html#module-structure>
  data Module =
    Module {
      moduleName :: ShortByteString,
      moduleSourceFileName :: ShortByteString,
      -- | a 'DataLayout', if specified, must match that of the eventual code generator
      moduleDataLayout :: Maybe DataLayout,
      moduleTargetTriple :: Maybe ShortByteString,
      moduleDefinitions :: [Definition]
    }
    deriving (Eq, Read, Show, Typeable, Data, Generic)
  
  -- | helper for making 'Module's
  defaultModule :: Module
  defaultModule =
    Module {
      moduleName = "<string>",
      moduleSourceFileName = "<string>",
      moduleDataLayout = Nothing,
      moduleTargetTriple = Nothing,
      moduleDefinitions = []
    }
  