  | 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  supports is less than pretty , so be it .
module LLVM.General.AST (
  Module(..), defaultModule,
  Definition(..),
  Global(GlobalVariable, GlobalAlias, Function), 
        globalVariableDefaults,
        globalAliasDefaults,
        functionDefaults,
  Parameter(..),
  BasicBlock(..),
  module LLVM.General.AST.Instruction,
  module LLVM.General.AST.Name,
  module LLVM.General.AST.Operand,
  module LLVM.General.AST.Type
  ) where

import LLVM.General.Prelude

import LLVM.General.AST.Name
import LLVM.General.AST.Type (Type(..), FloatingPointFormat(..))
import LLVM.General.AST.Global
import LLVM.General.AST.Operand
import LLVM.General.AST.Instruction
import LLVM.General.AST.DataLayout
import qualified LLVM.General.AST.Attribute as A
import qualified LLVM.General.AST.COMDAT as COMDAT

-- | Any thing which can be at the top level of a 'Module'
data Definition 
  = GlobalDefinition Global
  | TypeDefinition Name (Maybe Type)
  | MetadataNodeDefinition MetadataNodeID [Maybe Operand]
  | NamedMetadataDefinition String [MetadataNodeID]
  | ModuleInlineAssembly String
  | FunctionAttributes A.GroupID [A.FunctionAttribute]
  | COMDAT String COMDAT.SelectionKind
    deriving (Eq, Read, Show, Typeable, Data)

-- | <#module-structure>
data Module = 
  Module {
    moduleName :: String,
  | a ' DataLayout ' , if specified , must match that of the eventual code generator
    moduleDataLayout :: Maybe DataLayout, 
    moduleTargetTriple :: Maybe String,
    moduleDefinitions :: [Definition]
  } 
  deriving (Eq, Read, Show, Typeable, Data)

-- | helper for making 'Module's
defaultModule = 
  Module {
    moduleName = "<string>",
    moduleDataLayout = Nothing,
    moduleTargetTriple = Nothing,
    moduleDefinitions = []
  }

 | Any thing which can be at the top level of a 'Module'
 | <#module-structure>
 | helper for making 'Module's
  | 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  supports is less than pretty , so be it .
module LLVM.General.AST (
  Module(..), defaultModule,
  Definition(..),
  Global(GlobalVariable, GlobalAlias, Function), 
        globalVariableDefaults,
        globalAliasDefaults,
        functionDefaults,
  Parameter(..),
  BasicBlock(..),
  module LLVM.General.AST.Instruction,
  module LLVM.General.AST.Name,
  module LLVM.General.AST.Operand,
  module LLVM.General.AST.Type
  ) where

import LLVM.General.Prelude

import LLVM.General.AST.Name
import LLVM.General.AST.Type (Type(..), FloatingPointFormat(..))
import LLVM.General.AST.Global
import LLVM.General.AST.Operand
import LLVM.General.AST.Instruction
import LLVM.General.AST.DataLayout
import qualified LLVM.General.AST.Attribute as A
import qualified LLVM.General.AST.COMDAT as COMDAT

data Definition 
  = GlobalDefinition Global
  | TypeDefinition Name (Maybe Type)
  | MetadataNodeDefinition MetadataNodeID [Maybe Operand]
  | NamedMetadataDefinition String [MetadataNodeID]
  | ModuleInlineAssembly String
  | FunctionAttributes A.GroupID [A.FunctionAttribute]
  | COMDAT String COMDAT.SelectionKind
    deriving (Eq, Read, Show, Typeable, Data)

data Module = 
  Module {
    moduleName :: String,
  | a ' DataLayout ' , if specified , must match that of the eventual code generator
    moduleDataLayout :: Maybe DataLayout, 
    moduleTargetTriple :: Maybe String,
    moduleDefinitions :: [Definition]
  } 
  deriving (Eq, Read, Show, Typeable, Data)

defaultModule = 
  Module {
    moduleName = "<string>",
    moduleDataLayout = Nothing,
    moduleTargetTriple = Nothing,
    moduleDefinitions = []
  }
