summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNick Fitzgerald <fitzgen@gmail.com>2017-02-15 11:28:29 -0800
committerNick Fitzgerald <fitzgen@gmail.com>2017-02-21 08:39:16 -0800
commitcf3b4599d59207d403c682f39f896f512b0b4b76 (patch)
tree9aa676d0f3a896434a5958894cef9a084c751a00 /src
parent83c1a9594f5827451b7536352d53889b75230a57 (diff)
Add more `EdgeKind`s
Diffstat (limited to 'src')
-rw-r--r--src/ir/comp.rs16
-rw-r--r--src/ir/function.rs6
-rw-r--r--src/ir/item.rs4
-rw-r--r--src/ir/traversal.rs124
-rw-r--r--src/ir/ty.rs16
5 files changed, 143 insertions, 23 deletions
diff --git a/src/ir/comp.rs b/src/ir/comp.rs
index 6a9b8cb1..492c1a98 100644
--- a/src/ir/comp.rs
+++ b/src/ir/comp.rs
@@ -1040,10 +1040,10 @@ impl Trace for CompInfo {
if let Some(template) = self.specialized_template() {
// This is an instantiation of a template declaration with concrete
// template type arguments.
- tracer.visit(template);
+ tracer.visit_kind(template, EdgeKind::TemplateDeclaration);
let args = item.applicable_template_args(context);
for a in args {
- tracer.visit(a);
+ tracer.visit_kind(a, EdgeKind::TemplateArgument);
}
} else {
let params = item.applicable_template_args(context);
@@ -1055,27 +1055,27 @@ impl Trace for CompInfo {
}
for base in self.base_members() {
- tracer.visit(base.ty);
+ tracer.visit_kind(base.ty, EdgeKind::BaseMember);
}
for field in self.fields() {
- tracer.visit(field.ty());
+ tracer.visit_kind(field.ty(), EdgeKind::Field);
}
for &ty in self.inner_types() {
- tracer.visit(ty);
+ tracer.visit_kind(ty, EdgeKind::InnerType);
}
for &var in self.inner_vars() {
- tracer.visit(var);
+ tracer.visit_kind(var, EdgeKind::InnerVar);
}
for method in self.methods() {
- tracer.visit(method.signature);
+ tracer.visit_kind(method.signature, EdgeKind::Method);
}
for &ctor in self.constructors() {
- tracer.visit(ctor);
+ tracer.visit_kind(ctor, EdgeKind::Constructor);
}
}
}
diff --git a/src/ir/function.rs b/src/ir/function.rs
index daa30b89..2a13b9f0 100644
--- a/src/ir/function.rs
+++ b/src/ir/function.rs
@@ -3,7 +3,7 @@
use super::context::{BindgenContext, ItemId};
use super::dot::DotAttributes;
use super::item::Item;
-use super::traversal::{Trace, Tracer};
+use super::traversal::{EdgeKind, Trace, Tracer};
use super::ty::TypeKind;
use clang;
use clang_sys::CXCallingConv;
@@ -336,10 +336,10 @@ impl Trace for FunctionSig {
fn trace<T>(&self, _: &BindgenContext, tracer: &mut T, _: &())
where T: Tracer,
{
- tracer.visit(self.return_type());
+ tracer.visit_kind(self.return_type(), EdgeKind::FunctionReturn);
for &(_, ty) in self.argument_types() {
- tracer.visit(ty);
+ tracer.visit_kind(ty, EdgeKind::FunctionParameter);
}
}
}
diff --git a/src/ir/item.rs b/src/ir/item.rs
index 00e3a30d..21b27f07 100644
--- a/src/ir/item.rs
+++ b/src/ir/item.rs
@@ -7,7 +7,7 @@ use super::dot::{DotAttributes};
use super::function::Function;
use super::item_kind::ItemKind;
use super::module::Module;
-use super::traversal::{Trace, Tracer};
+use super::traversal::{EdgeKind, Trace, Tracer};
use super::ty::{TemplateDeclaration, Type, TypeKind};
use clang;
use clang_sys;
@@ -205,7 +205,7 @@ impl Trace for Item {
tracer.visit(fun.signature());
}
ItemKind::Var(ref var) => {
- tracer.visit(var.ty());
+ tracer.visit_kind(var.ty(), EdgeKind::VarType);
}
ItemKind::Module(_) => {
// Module -> children edges are "weak", and we do not want to
diff --git a/src/ir/traversal.rs b/src/ir/traversal.rs
index 8c5e32cf..30772aad 100644
--- a/src/ir/traversal.rs
+++ b/src/ir/traversal.rs
@@ -44,22 +44,137 @@ impl Into<ItemId> for Edge {
}
/// The kind of edge reference. This is useful when we wish to only consider
-/// certain kinds of edges for a particular traversal.
+/// certain kinds of edges for a particular traversal or analysis.
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum EdgeKind {
/// A generic, catch-all edge.
Generic,
/// An edge from a template declaration, to the definition of a named type
- /// parameter. For example, the edge Foo -> T in the following snippet:
+ /// parameter. For example, the edge from `Foo<T>` to `T` in the following
+ /// snippet:
///
/// ```C++
/// template<typename T>
+ /// class Foo { };
+ /// ```
+ TemplateParameterDefinition,
+
+ /// An edge from a template instantiation to the template declaration that
+ /// is being instantiated. For example, the edge from `Foo<int>` to
+ /// to `Foo<T>`:
+ ///
+ /// ```C++
+ /// template<typename T>
+ /// class Foo { };
+ ///
+ /// using Bar = Foo<int>;
+ /// ```
+ TemplateDeclaration,
+
+ /// An edge from a template instantiation to its template argument. For
+ /// example, `Foo<Bar>` to `Bar`:
+ ///
+ /// ```C++
+ /// template<typename T>
+ /// class Foo { };
+ ///
+ /// class Bar { };
+ ///
+ /// using FooBar = Foo<Bar>;
+ /// ```
+ TemplateArgument,
+
+ /// An edge from a compound type to one of its base member types. For
+ /// example, the edge from `Bar` to `Foo`:
+ ///
+ /// ```C++
+ /// class Foo { };
+ ///
+ /// class Bar : public Foo { };
+ /// ```
+ BaseMember,
+
+ /// An edge from a compound type to the types of one of its fields. For
+ /// example, the edge from `Foo` to `int`:
+ ///
+ /// ```C++
/// class Foo {
/// int x;
/// };
/// ```
- TemplateParameterDefinition,
+ Field,
+
+ /// An edge from an class or struct type to an inner type member. For
+ /// example, the edge from `Foo` to `Foo::Bar` here:
+ ///
+ /// ```C++
+ /// class Foo {
+ /// struct Bar { };
+ /// };
+ /// ```
+ InnerType,
+
+ /// An edge from an class or struct type to an inner static variable. For
+ /// example, the edge from `Foo` to `Foo::BAR` here:
+ ///
+ /// ```C++
+ /// class Foo {
+ /// static const char* BAR;
+ /// };
+ /// ```
+ InnerVar,
+
+ /// An edge from a class or struct type to one of its method functions. For
+ /// example, the edge from `Foo` to `Foo::bar`:
+ ///
+ /// ```C++
+ /// class Foo {
+ /// bool bar(int x, int y);
+ /// };
+ /// ```
+ Method,
+
+ /// An edge from a class or struct type to one of its constructor
+ /// functions. For example, the edge from `Foo` to `Foo::Foo(int x, int y)`:
+ ///
+ /// ```C++
+ /// class Foo {
+ /// int my_x;
+ /// int my_y;
+ ///
+ /// public:
+ /// Foo(int x, int y);
+ /// };
+ /// ```
+ Constructor,
+
+ /// An edge from a function declaration to its return type. For example, the
+ /// edge from `foo` to `int`:
+ ///
+ /// ```C++
+ /// int foo(char* string);
+ /// ```
+ FunctionReturn,
+
+ /// An edge from a function declaration to one of its parameter types. For
+ /// example, the edge from `foo` to `char*`:
+ ///
+ /// ```C++
+ /// int foo(char* string);
+ /// ```
+ FunctionParameter,
+
+ /// An edge from a static variable to its type. For example, the edge from
+ /// `FOO` to `const char*`:
+ ///
+ /// ```C++
+ /// static const char* FOO;
+ /// ```
+ VarType,
+
+ /// An edge from a non-templated alias or typedef to the referenced type.
+ TypeReference,
}
/// A predicate to allow visiting only sub-sets of the whole IR graph by
@@ -211,7 +326,8 @@ impl<F> Tracer for F
}
/// Trace all of the outgoing edges to other items. Implementations should call
-/// `tracer.visit(edge)` for each of their outgoing edges.
+/// one of `tracer.visit(edge)` or `tracer.visit_kind(edge, EdgeKind::Whatever)`
+/// for each of their outgoing edges.
pub trait Trace {
/// If a particular type needs extra information beyond what it has in
/// `self` and `context` to find its referenced items, its implementation
diff --git a/src/ir/ty.rs b/src/ir/ty.rs
index 1b5ecc3c..834a5c1b 100644
--- a/src/ir/ty.rs
+++ b/src/ir/ty.rs
@@ -10,7 +10,7 @@ use super::int::IntKind;
use super::item::{Item, ItemAncestors};
use super::layout::Layout;
use super::objc::ObjCInterface;
-use super::traversal::{Trace, Tracer};
+use super::traversal::{EdgeKind, Trace, Tracer};
use clang::{self, Cursor};
use parse::{ClangItemParser, ParseError, ParseResult};
use std::io;
@@ -1245,14 +1245,18 @@ impl Trace for Type {
TypeKind::Array(inner, _) |
TypeKind::Alias(inner) |
TypeKind::ResolvedTypeRef(inner) => {
- tracer.visit(inner);
+ tracer.visit_kind(inner, EdgeKind::TypeReference);
+ }
+ TypeKind::TemplateAlias(inner, ref template_params) => {
+ tracer.visit_kind(inner, EdgeKind::TypeReference);
+ for &item in template_params {
+ tracer.visit_kind(item, EdgeKind::TemplateParameterDefinition);
+ }
}
-
- TypeKind::TemplateAlias(inner, ref template_args) |
TypeKind::TemplateInstantiation(inner, ref template_args) => {
- tracer.visit(inner);
+ tracer.visit_kind(inner, EdgeKind::TemplateDeclaration);
for &item in template_args {
- tracer.visit(item);
+ tracer.visit_kind(item, EdgeKind::TemplateArgument);
}
}
TypeKind::Comp(ref ci) => ci.trace(context, tracer, item),