diff options
Diffstat (limited to '')
-rw-r--r-- | third_party/rust/bindgen/ir/module.rs | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/third_party/rust/bindgen/ir/module.rs b/third_party/rust/bindgen/ir/module.rs new file mode 100644 index 0000000000..d5aca94a6e --- /dev/null +++ b/third_party/rust/bindgen/ir/module.rs @@ -0,0 +1,95 @@ +//! Intermediate representation for modules (AKA C++ namespaces). + +use super::context::BindgenContext; +use super::dot::DotAttributes; +use super::item::ItemSet; +use crate::clang; +use crate::parse::{ClangSubItemParser, ParseError, ParseResult}; +use crate::parse_one; +use std::io; + +/// Whether this module is inline or not. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub enum ModuleKind { + /// This module is not inline. + Normal, + /// This module is inline, as in `inline namespace foo {}`. + Inline, +} + +/// A module, as in, a C++ namespace. +#[derive(Clone, Debug)] +pub struct Module { + /// The name of the module, or none if it's anonymous. + name: Option<String>, + /// The kind of module this is. + kind: ModuleKind, + /// The children of this module, just here for convenience. + children: ItemSet, +} + +impl Module { + /// Construct a new `Module`. + pub fn new(name: Option<String>, kind: ModuleKind) -> Self { + Module { + name, + kind, + children: ItemSet::new(), + } + } + + /// Get this module's name. + pub fn name(&self) -> Option<&str> { + self.name.as_deref() + } + + /// Get a mutable reference to this module's children. + pub fn children_mut(&mut self) -> &mut ItemSet { + &mut self.children + } + + /// Get this module's children. + pub fn children(&self) -> &ItemSet { + &self.children + } + + /// Whether this namespace is inline. + pub fn is_inline(&self) -> bool { + self.kind == ModuleKind::Inline + } +} + +impl DotAttributes for Module { + fn dot_attributes<W>( + &self, + _ctx: &BindgenContext, + out: &mut W, + ) -> io::Result<()> + where + W: io::Write, + { + writeln!(out, "<tr><td>ModuleKind</td><td>{:?}</td></tr>", self.kind) + } +} + +impl ClangSubItemParser for Module { + fn parse( + cursor: clang::Cursor, + ctx: &mut BindgenContext, + ) -> Result<ParseResult<Self>, ParseError> { + use clang_sys::*; + match cursor.kind() { + CXCursor_Namespace => { + let module_id = ctx.module(cursor); + ctx.with_module(module_id, |ctx| { + cursor.visit(|cursor| { + parse_one(ctx, cursor, Some(module_id.into())) + }) + }); + + Ok(ParseResult::AlreadyResolved(module_id.into())) + } + _ => Err(ParseError::Continue), + } + } +} |