content: 
  module DDC.Llvm.Syntax.Module
          ( -- * Modules
            Module    (..)
          , lookupCallConv
  
          , Global    (..)
          , typeOfGlobal
          , varOfGlobal
  
            -- * Static data.
          , Static    (..)
          , typeOfStatic)
  where
  import DDC.Llvm.Syntax.Function
  import DDC.Llvm.Syntax.Exp
  import DDC.Llvm.Syntax.Metadata
  import DDC.Llvm.Syntax.Type
  import DDC.Llvm.Syntax.Attr
  import Data.List
  import Control.Monad
  
  
  -- Module ---------------------------------------------------------------------
  -- | This is a top level container in LLVM.
  data Module
          = Module
          { -- | Comments to include at the start of the module.
            modComments  :: ![String]
  
            -- | Alias type definitions.
          , modAliases   :: ![TypeAlias]
  
            -- | Global variables to include in the module.
          , modGlobals   :: ![Global]
  
            -- | Functions used in this module but defined in other modules.
          , modFwdDecls  :: ![FunctionDecl]
  
            -- | Functions defined in this module.
          , modFuncs     :: ![Function]
  
            -- | Metdata for alias analysis
          , modMDecls    :: ![MDecl]
          }
  
  
  -- | Lookup the calling convention for this function,
  --   using the forward declarations as well as the function definitions.
  lookupCallConv :: String -> Module -> Maybe CallConv
  lookupCallConv name mm
          = liftM declCallConv
          $ find isFunctionDecl $ modFwdDecls mm ++ (map funDecl $ modFuncs mm)
          where isFunctionDecl decl
                  = declName decl == name
  
  
  -- Global ---------------------------------------------------------------------
  -- | A global mutable variable. Maybe defined or external
  data Global
          = GlobalStatic   !Var !Static
          | GlobalExternal !Var
          deriving Show
  
  
  -- | Return the 'LlvmType' of the 'LMGlobal'
  typeOfGlobal :: Global -> Type
  typeOfGlobal gg
   = case gg of
          GlobalStatic v _        -> typeOfVar v
          GlobalExternal v        -> typeOfVar v
  
  
  -- | Return the 'LlvmVar' part of a 'LMGlobal'
  varOfGlobal :: Global -> Var
  varOfGlobal gg
   = case gg of
          GlobalStatic v _        -> v
          GlobalExternal v        -> v
  
  
  -- Static ---------------------------------------------------------------------
  -- | Llvm Static Data.
  --   These represent the possible global level variables and constants.
  data Static
          -- | A comment in a static section.
          = StaticComment !String         -- TODO: kill this, has no type.
  
          -- | A static variant of a literal value.
          | StaticLit     !Lit
  
          -- | For uninitialised data.
          | StaticUninitType !Type
  
          -- | Defines a static 'LMString'.
          | StaticStr     !String   !Type
  
          -- | A static array.
          | StaticArray   ![Static] !Type
  
          -- | A static structure type.
          | StaticStruct  ![Static] !Type
  
          -- | A pointer to other data.
          | StaticPointer !Var
  
          -- Static expressions.
          -- | Pointer to Pointer conversion.
          | StaticBitc    !Static !Type
  
          -- | Pointer to Integer conversion.
          | StaticPtoI    !Static !Type
  
          -- | Constant addition operation.
          | StaticAdd     !Static !Static
  
          -- | Constant subtraction operation.
          | StaticSub     !Static !Static
          deriving (Show)
  
  
  -- | Return the 'LlvmType' of the 'LlvmStatic'.
  typeOfStatic :: Static -> Type
  typeOfStatic ss
   = case ss of
          StaticComment{}
           -> error "ddc-core-llvm.typeOfStatic: can't call getStatType on LMComment!"
  
          StaticLit   l           -> typeOfLit l
          StaticUninitType t      -> t
          StaticStr    _ t        -> t
          StaticArray  _ t        -> t
          StaticStruct _ t        -> t
          StaticPointer v         -> typeOfVar v
          StaticBitc   _ t        -> t
          StaticPtoI   _ t        -> t
          StaticAdd    t _        -> typeOfStatic t
          StaticSub    t _        -> typeOfStatic t
  
  
  