summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Fitzgerald <fitzgen@gmail.com>2017-02-17 10:34:47 -0800
committerNick Fitzgerald <fitzgen@gmail.com>2017-02-17 17:45:14 -0800
commit40943962f21cecad4c3e558b03287cd315a4fd84 (patch)
treee1b0a33a3a79386d111a6063a868812db2db60aa
parent28c750821aefa610c8b3047e6e6e449d85daa1ab (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.rs14
-rw-r--r--src/ir/item.rs13
-rw-r--r--src/ir/item_kind.rs20
-rw-r--r--src/ir/module.rs12
-rw-r--r--src/ir/ty.rs57
-rw-r--r--src/ir/var.rs18
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)