ensureCDecl :: String -> FType -> [FType] -> Codegen Operand
ensureCDecl name rty argtys = do
  syms <- gets foreignSyms
  case M.lookup name syms of
    Nothing -> do addGlobal (ffunDecl name rty argtys)
                  modify $ \s -> s { foreignSyms = M.insert name (rty, argtys) (foreignSyms s) }
    Just (rty', argtys') -> unless (rty == rty' && argtys == argtys') . fail $
                            "Mismatched type declarations for foreign symbol \"" ++ name ++ "\": " ++ show (rty, argtys) ++ " vs " ++ show (rty', argtys')
  return $ ConstantOperand (C.GlobalReference (Name name))
ensureCDecl :: String -> FType -> [FType] -> Codegen Operand
ensureCDecl name rty argtys = do
  syms <- gets foreignSyms
  case M.lookup name syms of
    Nothing -> do addGlobal (ffunDecl name rty argtys)
                  modify $ \s -> s { foreignSyms = M.insert name (rty, argtys) (foreignSyms s) }
    Just (rty', argtys') -> unless (rty == rty' && argtys == argtys') . fail $
                            "Mismatched type declarations for foreign symbol \"" ++ name ++ "\": " ++ show (rty, argtys) ++ " vs " ++ show (rty', argtys')
  return $ ConstantOperand (C.GlobalReference (Name name))
ensureCDecl name rty argtys = do
  syms <- gets foreignSyms
  case M.lookup name syms of
    Nothing -> do addGlobal (ffunDecl name rty argtys)
                  modify $ \s -> s { foreignSyms = M.insert name (rty, argtys) (foreignSyms s) }
    Just (rty', argtys') -> unless (rty == rty' && argtys == argtys') . fail $
                            "Mismatched type declarations for foreign symbol \"" ++ name ++ "\": " ++ show (rty, argtys) ++ " vs " ++ show (rty', argtys')
  return $ ConstantOperand (C.GlobalReference (Name name))