diff options
author | Nick Fitzgerald <fitzgen@gmail.com> | 2017-02-17 10:34:47 -0800 |
---|---|---|
committer | Nick Fitzgerald <fitzgen@gmail.com> | 2017-02-17 17:45:14 -0800 |
commit | 40943962f21cecad4c3e558b03287cd315a4fd84 (patch) | |
tree | e1b0a33a3a79386d111a6063a868812db2db60aa | |
parent | 28c750821aefa610c8b3047e6e6e449d85daa1ab (diff) |
Implement DotAttribute for a bunch of types
This gives us more debug information in the emitted graphviz dot files.
-rw-r--r-- | src/ir/function.rs | 14 | ||||
-rw-r--r-- | src/ir/item.rs | 13 | ||||
-rw-r--r-- | src/ir/item_kind.rs | 20 | ||||
-rw-r--r-- | src/ir/module.rs | 12 | ||||
-rw-r--r-- | src/ir/ty.rs | 57 | ||||
-rw-r--r-- | src/ir/var.rs | 18 |
6 files changed, 126 insertions, 8 deletions
diff --git a/src/ir/function.rs b/src/ir/function.rs index 22b9c9b0..daa30b89 100644 --- a/src/ir/function.rs +++ b/src/ir/function.rs @@ -1,12 +1,14 @@ //! Intermediate representation for C/C++ functions and methods. use super::context::{BindgenContext, ItemId}; +use super::dot::DotAttributes; use super::item::Item; use super::traversal::{Trace, Tracer}; use super::ty::TypeKind; use clang; use clang_sys::CXCallingConv; use parse::{ClangItemParser, ClangSubItemParser, ParseError, ParseResult}; +use std::io; use syntax::abi; /// A function declaration, with a signature, arguments, and argument names. @@ -59,6 +61,18 @@ impl Function { } } +impl DotAttributes for Function { + fn dot_attributes<W>(&self, _ctx: &BindgenContext, out: &mut W) -> io::Result<()> + where W: io::Write + { + if let Some(ref mangled) = self.mangled_name { + try!(writeln!(out, "<tr><td>mangled name</td><td>{}</td></tr>", mangled)); + } + + Ok(()) + } +} + /// A function signature. #[derive(Debug)] pub struct FunctionSig { diff --git a/src/ir/item.rs b/src/ir/item.rs index 48a70fc6..bd401aba 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -920,13 +920,12 @@ impl DotAttributes for Item { fn dot_attributes<W>(&self, ctx: &BindgenContext, out: &mut W) -> io::Result<()> where W: io::Write { - writeln!(out, - "<tr><td>{:?}</td></tr> - <tr><td>name</td><td>{}</td></tr> - <tr><td>kind</td><td>{}</td></tr>", - self.id, - self.name(ctx).get(), - self.kind.kind_name()) + try!(writeln!(out, + "<tr><td>{:?}</td></tr> + <tr><td>name</td><td>{}</td></tr>", + self.id, + self.name(ctx).get())); + self.kind.dot_attributes(ctx, out) } } diff --git a/src/ir/item_kind.rs b/src/ir/item_kind.rs index 3ff06731..6dfd6764 100644 --- a/src/ir/item_kind.rs +++ b/src/ir/item_kind.rs @@ -1,5 +1,8 @@ //! Different variants of an `Item` in our intermediate representation. +use std::io; +use super::context::BindgenContext; +use super::dot::DotAttributes; use super::function::Function; use super::module::Module; use super::ty::Type; @@ -39,7 +42,7 @@ impl ItemKind { ItemKind::Type(..) => "Type", ItemKind::Function(..) => "Function", ItemKind::Var(..) => "Var" - } + } } /// Is this a module? @@ -122,3 +125,18 @@ impl ItemKind { self.as_var().expect("Not a var") } } + +impl DotAttributes for ItemKind { + fn dot_attributes<W>(&self, ctx: &BindgenContext, out: &mut W) -> io::Result<()> + where W: io::Write + { + try!(writeln!(out, "<tr><td>kind</td><td>{}</td></tr>", self.kind_name())); + + match *self { + ItemKind::Module(ref module) => module.dot_attributes(ctx, out), + ItemKind::Type(ref ty) => ty.dot_attributes(ctx, out), + ItemKind::Function(ref func) => func.dot_attributes(ctx, out), + ItemKind::Var(ref var) => var.dot_attributes(ctx, out), + } + } +} diff --git a/src/ir/module.rs b/src/ir/module.rs index 6b6c535b..6787e3f9 100644 --- a/src/ir/module.rs +++ b/src/ir/module.rs @@ -1,6 +1,8 @@ //! Intermediate representation for modules (AKA C++ namespaces). +use std::io; use super::context::{BindgenContext, ItemId}; +use super::dot::DotAttributes; use clang; use parse::{ClangSubItemParser, ParseError, ParseResult}; use parse_one; @@ -56,6 +58,16 @@ impl Module { } } +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) diff --git a/src/ir/ty.rs b/src/ir/ty.rs index c3ec4039..44a88744 100644 --- a/src/ir/ty.rs +++ b/src/ir/ty.rs @@ -3,6 +3,7 @@ use super::comp::CompInfo; use super::context::{BindgenContext, ItemId}; use super::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault}; +use super::dot::DotAttributes; use super::enum_ty::Enum; use super::function::FunctionSig; use super::int::IntKind; @@ -12,6 +13,7 @@ use super::objc::ObjCInterface; use super::traversal::{Trace, Tracer}; use clang::{self, Cursor}; use parse::{ClangItemParser, ParseError, ParseResult}; +use std::io; use std::mem; /// Template declaration related methods. @@ -384,6 +386,61 @@ impl Type { } } +impl DotAttributes for Type { + fn dot_attributes<W>(&self, ctx: &BindgenContext, out: &mut W) -> io::Result<()> + where W: io::Write + { + if let Some(ref layout) = self.layout { + try!(writeln!(out, + "<tr><td>size</td><td>{}</td></tr> + <tr><td>align</td><td>{}</td></tr>", + layout.size, + layout.align)); + if layout.packed { + try!(writeln!(out, "<tr><td>packed</td><td>true</td></tr>")); + } + } + + if self.is_const { + try!(writeln!(out, "<tr><td>const</td><td>true</td></tr>")); + } + + self.kind.dot_attributes(ctx, out) + } +} + +impl DotAttributes for TypeKind { + fn dot_attributes<W>(&self, _ctx: &BindgenContext, out: &mut W) -> io::Result<()> + where W: io::Write + { + write!(out, + "<tr><td>TypeKind</td><td>{}</td></tr>", + match *self { + TypeKind::Void => "Void", + TypeKind::NullPtr => "NullPtr", + TypeKind::Comp(..) => "Comp", + TypeKind::Int(..) => "Int", + TypeKind::Float(..) => "Float", + TypeKind::Complex(..) => "Complex", + TypeKind::Alias(..) => "Alias", + TypeKind::TemplateAlias(..) => "TemplateAlias", + TypeKind::Array(..) => "Array", + TypeKind::Function(..) => "Function", + TypeKind::Enum(..) => "Enum", + TypeKind::Pointer(..) => "Pointer", + TypeKind::BlockPointer => "BlockPointer", + TypeKind::Reference(..) => "Reference", + TypeKind::TemplateInstantiation(..) => "TemplateInstantiation", + TypeKind::ResolvedTypeRef(..) => "ResolvedTypeRef", + TypeKind::Named => "Named", + TypeKind::ObjCInterface(..) => "ObjCInterface", + TypeKind::UnresolvedTypeRef(..) => { + unreachable!("there shouldn't be any more of these anymore") + } + }) + } +} + #[test] fn is_invalid_named_type_valid() { let ty = Type::new(Some("foo".into()), None, TypeKind::Named, false); diff --git a/src/ir/var.rs b/src/ir/var.rs index 6cfcdae7..c6d7a1c5 100644 --- a/src/ir/var.rs +++ b/src/ir/var.rs @@ -1,6 +1,7 @@ //! Intermediate representation of variables. use super::context::{BindgenContext, ItemId}; +use super::dot::DotAttributes; use super::function::cursor_mangling; use super::int::IntKind; use super::item::Item; @@ -8,6 +9,7 @@ use super::ty::{FloatKind, TypeKind}; use cexpr; use clang; use parse::{ClangItemParser, ClangSubItemParser, ParseError, ParseResult}; +use std::io; use std::num::Wrapping; /// The type for a constant variable. @@ -84,6 +86,22 @@ impl Var { } } +impl DotAttributes for Var { + fn dot_attributes<W>(&self, _ctx: &BindgenContext, out: &mut W) -> io::Result<()> + where W: io::Write + { + if self.is_const { + try!(writeln!(out, "<tr><td>const</td><td>true</td></tr>")); + } + + if let Some(ref mangled) = self.mangled_name { + try!(writeln!(out, "<tr><td>mangled name</td><td>{}</td></tr>", mangled)); + } + + Ok(()) + } +} + impl ClangSubItemParser for Var { fn parse(cursor: clang::Cursor, ctx: &mut BindgenContext) |