summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <ecoal95@gmail.com>2016-03-23 23:59:15 +0100
committerEmilio Cobos Álvarez <ecoal95@gmail.com>2016-03-23 23:59:32 +0100
commitaa9bd918772039e45a7e2ff5f90a36488776af4c (patch)
treebd2ea0f7d65f100c4644af63b7652896fbe8cfcf
parenta624bc81095df028859f0982b80881dc6cd38e28 (diff)
gen: Add option to replace types via annotations
This is limited to the same namespace, but well, it seems useful enough.
-rw-r--r--src/gen.rs12
-rw-r--r--src/parser.rs13
-rw-r--r--src/types.rs4
-rw-r--r--tests/headers/class_use_as.hpp15
4 files changed, 40 insertions, 4 deletions
diff --git a/src/gen.rs b/src/gen.rs
index a69ee861..e50cddea 100644
--- a/src/gen.rs
+++ b/src/gen.rs
@@ -52,6 +52,10 @@ impl<'r> GenCtx<'r> {
ret.reverse();
ret
}
+
+ fn current_module(&self) -> &Module {
+ self.module_map.get(&self.current_module_id).expect("Module not found!")
+ }
}
fn first<A, B>((val, _): (A, B)) -> A {
@@ -448,7 +452,9 @@ fn gen_globals(mut ctx: &mut GenCtx,
let mut defs = vec!();
gs = remove_redundant_decl(gs);
- for g in gs.into_iter() {
+ for mut g in gs.into_iter() {
+ // XXX unify with anotations both type_blacklisted
+ // and type_opaque (which actually doesn't mean the same).
if type_blacklisted(ctx, &g) {
continue;
}
@@ -462,6 +468,10 @@ fn gen_globals(mut ctx: &mut GenCtx,
continue;
}
+ if let Some(substituted) = ctx.current_module().translations.get(&g.name()) {
+ g = substituted.clone();
+ }
+
match g {
GType(ti) => {
let t = ti.borrow().clone();
diff --git a/src/parser.rs b/src/parser.rs
index 538d5d9c..8db8031b 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -467,6 +467,7 @@ fn opaque_ty(ctx: &mut ClangParserCtx, ty: &cx::Type) {
struct Annotations {
opaque: bool,
hide: bool,
+ use_as: Option<String>,
}
impl Annotations {
@@ -474,6 +475,7 @@ impl Annotations {
let mut anno = Annotations {
opaque: false,
hide: false,
+ use_as: None,
};
anno.parse(&cursor.comment());
@@ -487,10 +489,10 @@ impl Annotations {
comment.get_tag_attr_name(0) == "rustbindgen" {
for i in 0..comment.get_num_tag_attrs() {
let name = comment.get_tag_attr_name(i);
-
match name.as_str() {
"opaque" => self.opaque = true,
"hide" => self.hide = true,
+ "replaces" => self.use_as = Some(comment.get_tag_attr_value(i)),
_ => (),
}
}
@@ -860,7 +862,7 @@ fn visit_top(cursor: &Cursor,
| CXCursor_ClassDecl
| CXCursor_ClassTemplate => {
let anno = Annotations::new(cursor);
- fwd_decl(ctx, cursor, |ctx_| {
+ fwd_decl(ctx, cursor, move |ctx_| {
let decl = decl_name(ctx_, cursor);
let ci = decl.compinfo();
cursor.visit(|c, p| {
@@ -873,7 +875,12 @@ fn visit_top(cursor: &Cursor,
if anno.hide {
ci.borrow_mut().hide = true;
}
- ctx_.current_module_mut().globals.push(GComp(ci));
+ if let Some(other_type_name) = anno.use_as {
+ ci.borrow_mut().name = other_type_name.clone();
+ ctx_.current_module_mut().translations.insert(other_type_name, GComp(ci));
+ } else {
+ ctx_.current_module_mut().globals.push(GComp(ci));
+ }
});
CXChildVisit_Continue
}
diff --git a/src/types.rs b/src/types.rs
index 792965c2..925efdbf 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -32,6 +32,9 @@ pub struct Module {
pub parent_id: Option<ModuleId>,
// Just for convenience
pub children_ids: Vec<ModuleId>,
+ /// Types that must be substituted in this module,
+ /// in the form original_name -> substituted_type
+ pub translations: HashMap<String, Global>,
}
impl Module {
@@ -41,6 +44,7 @@ impl Module {
globals: vec![],
parent_id: parent_id,
children_ids: vec![],
+ translations: HashMap::new(),
}
}
diff --git a/tests/headers/class_use_as.hpp b/tests/headers/class_use_as.hpp
new file mode 100644
index 00000000..a4e36ded
--- /dev/null
+++ b/tests/headers/class_use_as.hpp
@@ -0,0 +1,15 @@
+
+/**
+ * <div rustbindgen="true" replaces="whatever"></div>
+ */
+struct whatever_replacement {
+ int replacement;
+};
+
+struct whatever {
+ int b;
+};
+
+struct container {
+ whatever c;
+};