diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ir/comp.rs | 16 | ||||
-rw-r--r-- | src/ir/function.rs | 6 | ||||
-rw-r--r-- | src/ir/item.rs | 4 | ||||
-rw-r--r-- | src/ir/traversal.rs | 124 | ||||
-rw-r--r-- | src/ir/ty.rs | 16 |
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), |