summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <me@emiliocobos.me>2016-04-04 18:16:30 +0200
committerEmilio Cobos Álvarez <me@emiliocobos.me>2016-04-04 18:16:30 +0200
commitc04a2c40d0f81175ad8e9237015fb9a0c2e30e5e (patch)
treefaee20bc99015f29d934500bbc3032daaa87cc6b
parentb6ebdb7ec36015d2d36adde90697dcc2f4b3a247 (diff)
gen: parser: Move name mangling to parser
-rw-r--r--src/gen.rs7
-rw-r--r--src/parser.rs16
-rw-r--r--tests/headers/class_nested.hpp2
3 files changed, 18 insertions, 7 deletions
diff --git a/src/gen.rs b/src/gen.rs
index 017271d5..a9620dba 100644
--- a/src/gen.rs
+++ b/src/gen.rs
@@ -984,10 +984,6 @@ fn cstruct_to_rs(ctx: &mut GenCtx, name: &str, ci: CompInfo) -> Vec<P<ast::Item>
if empty_name {
ei.borrow_mut().name = format!("{}_enum{}", name, anon_enum_count);
anon_enum_count += 1;
- } else {
- // Mangled name to deal with multiple definitions of the same inner type
- let new_name = [name, &*ei.borrow().name].join("_").to_owned();
- ei.borrow_mut().name = new_name;
}
let e = ei.borrow().clone();
@@ -1115,9 +1111,6 @@ fn cstruct_to_rs(ctx: &mut GenCtx, name: &str, ci: CompInfo) -> Vec<P<ast::Item>
fields.push(mk_blob_field(ctx, &field_name, c.layout));
methods.extend(gen_comp_methods(ctx, &field_name, 0, c.kind, &c.members, &mut extra).into_iter());
} else {
- // Mangled name to deal with multiple definitions of the same inner type
- let mangled_name = [name, &*rc_c.borrow().name].join("_").to_owned();
- rc_c.borrow_mut().name = mangled_name;
let name = comp_name(&ctx, rc_c.borrow().kind, &rc_c.borrow().name);
extra.extend(comp_to_rs(ctx, &name, rc_c.borrow().clone()).into_iter());
}
diff --git a/src/parser.rs b/src/parser.rs
index 9fef18f2..db141df0 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -621,6 +621,10 @@ fn visit_composite(cursor: &Cursor, parent: &Cursor,
// to globals otherwise it will be declared later and a global.
let decl = decl_name(ctx_, cursor);
let ci2 = decl.compinfo();
+ // Mangle the name to prevent multiple definitions
+ // of the same inner type to cause conflicts
+ let new_name = [&*ci.name, &*ci2.borrow().name].join("_").to_owned();
+ ci2.borrow_mut().name = new_name;
cursor.visit(|c, p| {
let mut ci_ = ci2.borrow_mut();
visit_composite(c, p, ctx_, &mut ci_)
@@ -649,9 +653,13 @@ fn visit_composite(cursor: &Cursor, parent: &Cursor,
}
CXCursor_EnumDecl => {
let anno = Annotations::new(cursor);
+
fwd_decl(ctx, cursor, |ctx_| {
let decl = decl_name(ctx_, cursor);
let ei = decl.enuminfo();
+ // Mangle the name to avoid name conflicts with inner types
+ let new_name = [&*ci.name, &*ei.borrow().name].join("_").to_owned();
+ ei.borrow_mut().name = new_name;
ei.borrow_mut().comment = cursor.raw_comment();
cursor.visit(|c, _: &Cursor| {
let mut ei_ = ei.borrow_mut();
@@ -752,6 +760,14 @@ fn visit_composite(cursor: &Cursor, parent: &Cursor,
if cursor.method_is_virtual() {
sig.args.insert(0, ("this".to_string(),TPtr(Box::new(TVoid), cursor.cur_type().is_const(), false, Layout::zero())));
} else {
+ // XXX This is weak and doesn't work if names are mangled further, but...
+ // We can't have access to the current Rc from here, so we can't pass the type
+ // here.
+ //
+ // Also, it would form an rc cycle.
+ //
+ // Possibly marking the "this" attribute with TOther or a similar marked value
+ // would be a better choice.
sig.args.insert(0, ("this".to_string(),
TPtr(Box::new(TNamed(Rc::new(RefCell::new(TypeInfo::new(ci.name.clone(), ctx.current_module_id, TVoid, Layout::zero()))))), cursor.cur_type().is_const(), false, Layout::zero())));
}
diff --git a/tests/headers/class_nested.hpp b/tests/headers/class_nested.hpp
index 670d418f..ab38d500 100644
--- a/tests/headers/class_nested.hpp
+++ b/tests/headers/class_nested.hpp
@@ -17,6 +17,8 @@ class Templated {
T member;
class Templated_inner {
+ public:
T* member_ptr;
+ void get() {}
};
};