Skip to content

Commit fac2daf

Browse files
committed
Make sure mangled functions and variables still link
If a variable or function name conflicts with a rust keyword, it has to be mangled (i.e., a "_" will be added in front of it). But we still have to make sure it links to the correct C symbol, so a link_name attribute has to be added.
1 parent 840a2ee commit fac2daf

File tree

1 file changed

+40
-16
lines changed

1 file changed

+40
-16
lines changed

gen.rs

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@ struct GenCtx {
1717
keywords: HashMap<~str, ()>
1818
}
1919

20-
fn rust_id(ctx: &GenCtx, name: ~str) -> ~str {
20+
fn rust_id(ctx: &GenCtx, name: ~str) -> (~str, bool) {
2121
if ctx.keywords.contains_key_ref(&name) {
22-
return ~"_" + name;
22+
(~"_" + name, true)
23+
} else {
24+
(move name, false)
2325
}
24-
return move name;
2526
}
2627

2728
fn unnamed_name(ctx: &GenCtx, name: ~str) -> ~str {
@@ -210,7 +211,7 @@ fn remove_redundent_decl(gs: &[Global]) -> ~[Global] {
210211

211212
fn ctypedef_to_rs(ctx: &GenCtx, name: ~str, ty: @Type) -> ~[@ast::item] {
212213
fn mk_item(ctx: &GenCtx, name: ~str, ty: @Type) -> @ast::item {
213-
let rust_name = rust_id(ctx, move name);
214+
let rust_name = rust_id(ctx, move name).first();
214215
let rust_ty = cty_to_rs(ctx, ty);
215216
let base = ast::item_ty(
216217
@{ id: ctx.ext_cx.next_id(),
@@ -257,7 +258,7 @@ fn cstruct_to_rs(ctx: &GenCtx, name: ~str, fields: ~[@FieldInfo]) -> @ast::item
257258
unnamed += 1;
258259
fmt!("unnamed_field%u", unnamed)
259260
} else {
260-
rust_id(ctx, copy f.name)
261+
rust_id(ctx, copy f.name).first()
261262
};
262263

263264
let f_ty = cty_to_rs(ctx, f.ty);
@@ -283,7 +284,7 @@ fn cstruct_to_rs(ctx: &GenCtx, name: ~str, fields: ~[@FieldInfo]) -> @ast::item
283284
~[]
284285
);
285286

286-
return @{ ident: ctx.ext_cx.ident_of(rust_id(ctx, move name)),
287+
return @{ ident: ctx.ext_cx.ident_of(rust_id(ctx, move name).first()),
287288
attrs: ~[],
288289
id: ctx.ext_cx.next_id(),
289290
node: move def,
@@ -327,15 +328,15 @@ fn cunion_to_rs(ctx: &GenCtx, name: ~str, fields: ~[@FieldInfo]) -> ~[@ast::item
327328
},
328329
~[]
329330
);
330-
let union_def = mk_item(ctx, rust_id(ctx, move name), move def);
331+
let union_def = mk_item(ctx, rust_id(ctx, move name).first(), move def);
331332

332333
let mut unnamed = 0;
333334
let fs = do fields.map |f| {
334335
let f_name = if str::is_empty(f.name) {
335336
unnamed += 1;
336337
fmt!("unnamed_field%u", unnamed)
337338
} else {
338-
rust_id(ctx, copy f.name)
339+
rust_id(ctx, copy f.name).first()
339340
};
340341

341342
let ret_ty = cty_to_rs(ctx, @TPtr(f.ty));
@@ -380,7 +381,7 @@ fn cunion_to_rs(ctx: &GenCtx, name: ~str, fields: ~[@FieldInfo]) -> ~[@ast::item
380381

381382
fn cenum_to_rs(ctx: &GenCtx, name: ~str, items: ~[@EnumItem], kind: IKind) -> ~[@ast::item] {
382383
let ty = @TInt(kind);
383-
let ty_def = ctypedef_to_rs(ctx, rust_id(ctx, move name), ty);
384+
let ty_def = ctypedef_to_rs(ctx, rust_id(ctx, move name).first(), ty);
384385
let val_ty = cty_to_rs(ctx, ty);
385386
let mut def = move ty_def;
386387

@@ -390,7 +391,7 @@ fn cenum_to_rs(ctx: &GenCtx, name: ~str, items: ~[@EnumItem], kind: IKind) -> ~[
390391
build::mk_int(ctx.ext_cx, dummy_sp(), it.val)
391392
);
392393

393-
let val_def = @{ ident: ctx.ext_cx.ident_of(rust_id(ctx, copy it.name)),
394+
let val_def = @{ ident: ctx.ext_cx.ident_of(rust_id(ctx, copy it.name).first()),
394395
attrs: ~[],
395396
id: ctx.ext_cx.next_id(),
396397
node: move cst,
@@ -404,9 +405,25 @@ fn cenum_to_rs(ctx: &GenCtx, name: ~str, items: ~[@EnumItem], kind: IKind) -> ~[
404405
return move def;
405406
}
406407

408+
fn mk_link_name_attr(name: ~str) -> ast::attribute {
409+
let lit = {node: ast::lit_str(@(move name)), span: dummy_sp()};
410+
let attr_val = {node: ast::meta_name_value(~"link_name", lit),
411+
span: dummy_sp()};
412+
let attr = {style: ast::attr_outer, value: move attr_val,
413+
is_sugared_doc: false};
414+
move {node: move attr, span: dummy_sp()}
415+
}
416+
407417
fn cvar_to_rs(ctx: &GenCtx, name: ~str, ty: @Type) -> @ast::foreign_item {
408-
return @{ ident: ctx.ext_cx.ident_of(rust_id(ctx, move name)),
409-
attrs: ~[],
418+
let (rust_name, was_mangled) = rust_id(ctx, copy name);
419+
420+
let mut attrs = ~[];
421+
if was_mangled {
422+
attrs.push(mk_link_name_attr(move name));
423+
}
424+
425+
return @{ ident: ctx.ext_cx.ident_of(move rust_name),
426+
attrs: move attrs,
410427
node: ast::foreign_item_const(cty_to_rs(ctx, ty)),
411428
id: ctx.ext_cx.next_id(),
412429
span: dummy_sp(),
@@ -434,7 +451,7 @@ fn cfunc_to_rs(ctx: &GenCtx, name: ~str, rty: @Type,
434451
unnamed += 1;
435452
fmt!("arg%u", unnamed)
436453
} else {
437-
rust_id(ctx, move n)
454+
rust_id(ctx, move n).first()
438455
};
439456

440457
let arg_ty = cty_to_rs(ctx, t);
@@ -468,8 +485,15 @@ fn cfunc_to_rs(ctx: &GenCtx, name: ~str, rty: @Type,
468485
~[]
469486
);
470487

471-
return @{ ident: ctx.ext_cx.ident_of(rust_id(ctx, move name)),
472-
attrs: ~[],
488+
let (rust_name, was_mangled) = rust_id(ctx, copy name);
489+
490+
let mut attrs = ~[];
491+
if was_mangled {
492+
attrs.push(mk_link_name_attr(move name));
493+
}
494+
495+
return @{ ident: ctx.ext_cx.ident_of(rust_name),
496+
attrs: move attrs,
473497
node: move decl,
474498
id: ctx.ext_cx.next_id(),
475499
span: dummy_sp(),
@@ -500,7 +524,7 @@ fn cty_to_rs(ctx: &GenCtx, ty: @Type) -> @ast::Ty {
500524
TPtr(t) => mk_ptrty(ctx, cty_to_rs(ctx, t)),
501525
TArray(t, s) => mk_arrty(ctx, cty_to_rs(ctx, t), s),
502526
TFunc(_, _, _) => mk_fnty(ctx),
503-
TNamed(ti) => mk_ty(ctx, rust_id(ctx, copy ti.name)),
527+
TNamed(ti) => mk_ty(ctx, rust_id(ctx, copy ti.name).first()),
504528
TComp(ci) => {
505529
ci.name = unnamed_name(ctx, copy ci.name);
506530
if ci.cstruct {

0 commit comments

Comments
 (0)