1 //! Intermediate representation for modules (AKA C++ namespaces). 2 3 use super::context::BindgenContext; 4 use super::dot::DotAttributes; 5 use super::item::ItemSet; 6 use crate::clang; 7 use crate::parse::{ClangSubItemParser, ParseError, ParseResult}; 8 use crate::parse_one; 9 10 use std::io; 11 12 /// Whether this module is inline or not. 13 #[derive(Debug, Copy, Clone, PartialEq, Eq)] 14 pub(crate) enum ModuleKind { 15 /// This module is not inline. 16 Normal, 17 /// This module is inline, as in `inline namespace foo {}`. 18 Inline, 19 } 20 21 /// A module, as in, a C++ namespace. 22 #[derive(Clone, Debug)] 23 pub(crate) struct Module { 24 /// The name of the module, or none if it's anonymous. 25 name: Option<String>, 26 /// The kind of module this is. 27 kind: ModuleKind, 28 /// The children of this module, just here for convenience. 29 children: ItemSet, 30 } 31 32 impl Module { 33 /// Construct a new `Module`. new(name: Option<String>, kind: ModuleKind) -> Self34 pub(crate) fn new(name: Option<String>, kind: ModuleKind) -> Self { 35 Module { 36 name, 37 kind, 38 children: ItemSet::new(), 39 } 40 } 41 42 /// Get this module's name. name(&self) -> Option<&str>43 pub(crate) fn name(&self) -> Option<&str> { 44 self.name.as_deref() 45 } 46 47 /// Get a mutable reference to this module's children. children_mut(&mut self) -> &mut ItemSet48 pub(crate) fn children_mut(&mut self) -> &mut ItemSet { 49 &mut self.children 50 } 51 52 /// Get this module's children. children(&self) -> &ItemSet53 pub(crate) fn children(&self) -> &ItemSet { 54 &self.children 55 } 56 57 /// Whether this namespace is inline. is_inline(&self) -> bool58 pub(crate) fn is_inline(&self) -> bool { 59 self.kind == ModuleKind::Inline 60 } 61 } 62 63 impl DotAttributes for Module { dot_attributes<W>( &self, _ctx: &BindgenContext, out: &mut W, ) -> io::Result<()> where W: io::Write,64 fn dot_attributes<W>( 65 &self, 66 _ctx: &BindgenContext, 67 out: &mut W, 68 ) -> io::Result<()> 69 where 70 W: io::Write, 71 { 72 writeln!(out, "<tr><td>ModuleKind</td><td>{:?}</td></tr>", self.kind) 73 } 74 } 75 76 impl ClangSubItemParser for Module { parse( cursor: clang::Cursor, ctx: &mut BindgenContext, ) -> Result<ParseResult<Self>, ParseError>77 fn parse( 78 cursor: clang::Cursor, 79 ctx: &mut BindgenContext, 80 ) -> Result<ParseResult<Self>, ParseError> { 81 use clang_sys::*; 82 match cursor.kind() { 83 CXCursor_Namespace => { 84 let module_id = ctx.module(cursor); 85 ctx.with_module(module_id, |ctx| { 86 cursor.visit_sorted(ctx, |ctx, child| { 87 parse_one(ctx, child, Some(module_id.into())) 88 }) 89 }); 90 91 Ok(ParseResult::AlreadyResolved(module_id.into())) 92 } 93 _ => Err(ParseError::Continue), 94 } 95 } 96 } 97