1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
#![allow(clippy::not_unsafe_ptr_arg_deref)]
#![warn(clippy::print_stdout)]
#![feature(range_contains)]
#![warn(
    clippy::print_stdout,
    clippy::unimplemented,
    clippy::doc_markdown,
    clippy::items_after_statements,
    clippy::match_same_arms,
    clippy::similar_names,
    clippy::single_match_else,
    clippy::use_self
)]

#[macro_use]
extern crate derive_more;

#[macro_use]
extern crate lazy_static;

macro_rules! generate_iterator {
    (
        $iter_name: ident,
        $info_type: ty,
        $len_fn: ident,
        $info_name: ident,
        $idx_name: ident,
        $idx_type: ty,
        $result_expr: expr,
        $result_type: ty,
    ) => {
        pub struct $iter_name {
            info: $info_type,
            cur: $idx_type,
            len: $idx_type,
        }

        impl $iter_name {
            fn new(info: $info_type) -> Self {
                Self {
                    info,
                    len: unsafe { bindings::$len_fn(info) },
                    cur: 0,
                }
            }

            pub fn idx(&self, $idx_name: $idx_type) -> Option<$result_type> {
                if (0..self.len).contains(&$idx_name) {
                    let $info_name = self.info;
                    Some($result_expr)
                } else {
                    None
                }
            }
        }

        impl Iterator for $iter_name {
            type Item = $result_type;

            fn next(&mut self) -> Option<$result_type> {
                if self.cur == self.len {
                    None
                } else {
                    let $idx_name = self.cur;
                    self.cur += 1;
                    let $info_name = self.info;
                    Some($result_expr)
                }
            }
        }

        impl ExactSizeIterator for $iter_name {
            fn len(&self) -> usize {
                self.len as usize
            }
        }
    };
}

pub use libfirm_rs_bindings as bindings;

mod entity;
mod graph;
mod mode;
pub mod nodes;
mod tarval;
pub mod types;

pub use self::{
    entity::Entity,
    graph::{Graph, VisitTime},
    mode::Mode,
    tarval::{Tarval, TarvalKind},
};

use std::sync::Once;

static INIT: Once = Once::new();
pub fn init() {
    INIT.call_once(|| unsafe {
        bindings::ir_init_library();
    });
}