diff options
author | Emilio Cobos Álvarez <ecoal95@gmail.com> | 2016-03-23 23:59:15 +0100 |
---|---|---|
committer | Emilio Cobos Álvarez <ecoal95@gmail.com> | 2016-03-23 23:59:32 +0100 |
commit | aa9bd918772039e45a7e2ff5f90a36488776af4c (patch) | |
tree | bd2ea0f7d65f100c4644af63b7652896fbe8cfcf | |
parent | a624bc81095df028859f0982b80881dc6cd38e28 (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.rs | 12 | ||||
-rw-r--r-- | src/parser.rs | 13 | ||||
-rw-r--r-- | src/types.rs | 4 | ||||
-rw-r--r-- | tests/headers/class_use_as.hpp | 15 |
4 files changed, 40 insertions, 4 deletions
@@ -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; +}; |