Skip to content

Commit 33e3f78

Browse files
committed
squash! Move code to a helpers module, ugly hack included.
1 parent c1a2199 commit 33e3f78

File tree

3 files changed

+138
-118
lines changed

3 files changed

+138
-118
lines changed

build.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ mod codegen {
1010

1111
quasi_codegen::expand(&src, &dst).unwrap();
1212
println!("cargo:rerun-if-changed=src/codegen/mod.rs");
13+
println!("cargo:rerun-if-changed=src/codegen/helpers.rs");
1314
}
1415
}
1516

src/codegen/helpers.rs

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/// Helpers for code generation that don't need macro expansion.
2+
3+
use aster;
4+
use ir::layout::Layout;
5+
use syntax::ast;
6+
use syntax::codemap::respan;
7+
use syntax::ptr::P;
8+
9+
10+
pub mod attributes {
11+
use aster;
12+
use syntax::ast;
13+
14+
pub fn repr(which: &str) -> ast::Attribute {
15+
aster::AstBuilder::new().attr().list("repr").words(&[which]).build()
16+
}
17+
18+
pub fn repr_list(which_ones: &[&str]) -> ast::Attribute {
19+
aster::AstBuilder::new().attr().list("repr").words(which_ones).build()
20+
}
21+
22+
pub fn derives(which_ones: &[&str]) -> ast::Attribute {
23+
aster::AstBuilder::new().attr().list("derive").words(which_ones).build()
24+
}
25+
26+
pub fn inline() -> ast::Attribute {
27+
aster::AstBuilder::new().attr().word("inline")
28+
}
29+
30+
pub fn doc(comment: &str) -> ast::Attribute {
31+
aster::AstBuilder::new().attr().doc(comment)
32+
}
33+
34+
pub fn link_name(name: &str) -> ast::Attribute {
35+
aster::AstBuilder::new().attr().name_value("link_name").str(name)
36+
}
37+
}
38+
39+
/// Generates a proper type for a field or type with a given `Layout`, that is,
40+
/// a type with the correct size and alignment restrictions.
41+
pub struct BlobTyBuilder {
42+
layout: Layout,
43+
}
44+
45+
impl BlobTyBuilder {
46+
pub fn new(layout: Layout) -> Self {
47+
BlobTyBuilder {
48+
layout: layout,
49+
}
50+
}
51+
52+
pub fn build(self) -> P<ast::Ty> {
53+
use std::cmp;
54+
55+
let ty_name = match self.layout.align {
56+
8 => "u64",
57+
4 => "u32",
58+
2 => "u16",
59+
1 | _ => "u8",
60+
};
61+
let data_len = if ty_name == "u8" {
62+
self.layout.size
63+
} else {
64+
self.layout.size / cmp::max(self.layout.align, 1)
65+
};
66+
67+
let inner_ty = aster::AstBuilder::new().ty().path().id(ty_name).build();
68+
if data_len == 1 {
69+
inner_ty
70+
} else {
71+
ArrayTyBuilder::new().with_len(data_len).build(inner_ty)
72+
}
73+
}
74+
}
75+
76+
pub struct ArrayTyBuilder {
77+
len: usize,
78+
}
79+
80+
impl ArrayTyBuilder {
81+
pub fn new() -> Self {
82+
ArrayTyBuilder {
83+
len: 0,
84+
}
85+
}
86+
87+
pub fn with_len(mut self, len: usize) -> Self {
88+
self.len = len;
89+
self
90+
}
91+
92+
pub fn build(self, ty: P<ast::Ty>) -> P<ast::Ty> {
93+
use syntax::codemap::DUMMY_SP;
94+
let size =
95+
ast::LitKind::Int(self.len as u64,
96+
ast::LitIntType::Unsigned(ast::UintTy::Us));
97+
let size = ast::ExprKind::Lit(P(respan(DUMMY_SP, size)));
98+
let array_kind = ast::TyKind::FixedLengthVec(ty,
99+
P(ast::Expr {
100+
id: ast::DUMMY_NODE_ID,
101+
node: size,
102+
span: DUMMY_SP,
103+
attrs: ast::ThinVec::new(),
104+
})
105+
);
106+
107+
P(ast::Ty {
108+
id: ast::DUMMY_NODE_ID,
109+
node: array_kind,
110+
span: DUMMY_SP,
111+
})
112+
}
113+
}

src/codegen/mod.rs

Lines changed: 24 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -23,31 +23,21 @@ use syntax::codemap::{Span, respan};
2323
use syntax::ptr::P;
2424
use aster;
2525

26+
// FIXME: This is shame, but we need to do this here since quasi eats the
27+
// includes in the "helpers" mod otherwise.
28+
mod helpers {
29+
include!("helpers.rs");
30+
}
31+
32+
use self::helpers::{attributes, ArrayTyBuilder, BlobTyBuilder};
33+
2634
fn root_import(ctx: &BindgenContext) -> P<ast::Item> {
2735
assert!(ctx.options().enable_cxx_namespaces, "Somebody messed it up");
2836
let root = ctx.root_module().canonical_name(ctx);
2937
let root_ident = ctx.rust_ident(&root);
3038
quote_item!(ctx.ext_cx(), use $root_ident;).unwrap()
3139
}
3240

33-
macro_rules! repr {
34-
($which:expr) => {{
35-
aster::AstBuilder::new().attr().list("repr").words(&[$which]).build()
36-
}}
37-
}
38-
39-
macro_rules! doc {
40-
($comment:expr) => {{
41-
aster::AstBuilder::new().attr().doc($comment)
42-
}}
43-
}
44-
45-
macro_rules! link_name {
46-
($name:expr) => {{
47-
aster::AstBuilder::new().attr().name_value("link_name").str($name)
48-
}}
49-
}
50-
5141
struct CodegenResult {
5242
items: Vec<P<ast::Item>>,
5343
saw_union: bool,
@@ -166,83 +156,6 @@ impl ForeignModBuilder {
166156
}
167157
}
168158

169-
struct ArrayTyBuilder {
170-
len: usize,
171-
}
172-
173-
// TODO: Aster seem to lack a array builder?
174-
impl ArrayTyBuilder {
175-
fn new() -> Self {
176-
ArrayTyBuilder {
177-
len: 0,
178-
}
179-
}
180-
181-
fn with_len(mut self, len: usize) -> Self {
182-
self.len = len;
183-
self
184-
}
185-
186-
fn build(self, ty: P<ast::Ty>) -> P<ast::Ty> {
187-
use syntax::codemap::DUMMY_SP;
188-
let size =
189-
ast::LitKind::Int(self.len as u64,
190-
ast::LitIntType::Unsigned(ast::UintTy::Us));
191-
let size = ast::ExprKind::Lit(P(respan(DUMMY_SP, size)));
192-
let array_kind = ast::TyKind::FixedLengthVec(ty,
193-
P(ast::Expr {
194-
id: ast::DUMMY_NODE_ID,
195-
node: size,
196-
span: DUMMY_SP,
197-
attrs: ast::ThinVec::new(),
198-
})
199-
);
200-
201-
P(ast::Ty {
202-
id: ast::DUMMY_NODE_ID,
203-
node: array_kind,
204-
span: DUMMY_SP,
205-
})
206-
}
207-
}
208-
209-
/// Generates a proper type for a field or type with a given `Layout`, that is,
210-
/// a type with the correct size and alignment restrictions.
211-
struct BlobTyBuilder {
212-
layout: Layout,
213-
}
214-
215-
impl BlobTyBuilder {
216-
fn new(layout: Layout) -> Self {
217-
BlobTyBuilder {
218-
layout: layout,
219-
}
220-
}
221-
222-
fn build(self) -> P<ast::Ty> {
223-
use std::cmp;
224-
225-
let ty_name = match self.layout.align {
226-
8 => "u64",
227-
4 => "u32",
228-
2 => "u16",
229-
1 | _ => "u8",
230-
};
231-
let data_len = if ty_name == "u8" {
232-
self.layout.size
233-
} else {
234-
self.layout.size / cmp::max(self.layout.align, 1)
235-
};
236-
237-
let inner_ty = aster::AstBuilder::new().ty().path().id(ty_name).build();
238-
if data_len == 1 {
239-
inner_ty
240-
} else {
241-
ArrayTyBuilder::new().with_len(data_len).build(inner_ty)
242-
}
243-
}
244-
}
245-
246159
/// A trait to convert a rust type into a pointer, optionally const, to the same
247160
/// type.
248161
///
@@ -366,9 +279,9 @@ impl CodeGenerator for Var {
366279
} else {
367280
let mut attrs = vec![];
368281
if let Some(mangled) = self.mangled_name() {
369-
attrs.push(link_name!(mangled));
282+
attrs.push(attributes::link_name(mangled));
370283
} else if name != self.name() {
371-
attrs.push(link_name!(self.name()));
284+
attrs.push(attributes::link_name(self.name()));
372285
}
373286

374287
let item = ast::ForeignItem {
@@ -501,7 +414,7 @@ impl<'a> CodeGenerator for Vtable<'a> {
501414
// For now, generate an empty struct, later we should generate function
502415
// pointers and whatnot.
503416
let vtable = aster::AstBuilder::new().item().pub_()
504-
.with_attr(repr!("C"))
417+
.with_attr(attributes::repr("C"))
505418
.struct_(self.canonical_name(ctx))
506419
.build();
507420
result.push(vtable);
@@ -628,16 +541,12 @@ impl CodeGenerator for CompInfo {
628541
let mut attributes = vec![];
629542
let mut needs_clone_impl = false;
630543
if let Some(comment) = item.comment() {
631-
attributes.push(doc!(comment));
544+
attributes.push(attributes::doc(comment));
632545
}
633546
if self.packed() {
634-
// TODO: reuse the repr! macro?
635-
let c_packed =
636-
aster::AstBuilder::new().attr().list("repr")
637-
.words(&["C", "packed"]).build();
638-
attributes.push(c_packed);
547+
attributes.push(attributes::repr_list(&["C", "packed"]));
639548
} else {
640-
attributes.push(repr!("C"));
549+
attributes.push(attributes::repr("C"));
641550
}
642551

643552
let mut derives = vec![];
@@ -662,9 +571,7 @@ impl CodeGenerator for CompInfo {
662571
}
663572

664573
if !derives.is_empty() {
665-
let derives = aster::AstBuilder::new().attr().list("derive")
666-
.words(&derives).build();
667-
attributes.push(derives)
574+
attributes.push(attributes::derives(&derives))
668575
}
669576

670577
let mut template_args_used = vec![false; applicable_template_args.len()];
@@ -809,7 +716,7 @@ impl CodeGenerator for CompInfo {
809716

810717
let mut attrs = vec![];
811718
if let Some(comment) = field.comment() {
812-
attrs.push(doc!(comment));
719+
attrs.push(attributes::doc(comment));
813720
}
814721
let field_name = match field.name() {
815722
Some(name) => ctx.rust_mangle(name).into_owned(),
@@ -1198,7 +1105,7 @@ impl MethodCodegen for Method {
11981105
};
11991106

12001107
let mut attrs = vec![];
1201-
attrs.push(aster::AstBuilder::new().attr().word("inline"));
1108+
attrs.push(attributes::inline());
12021109

12031110
let item = ast::ImplItem {
12041111
id: ast::DUMMY_NODE_ID,
@@ -1260,17 +1167,16 @@ impl CodeGenerator for Enum {
12601167
// FIXME: Rust forbids repr with empty enums. Remove this condition when
12611168
// this is allowed.
12621169
if !self.variants().is_empty() {
1263-
builder = builder.with_attr(repr!(repr_name));
1170+
builder = builder.with_attr(attributes::repr(repr_name));
12641171
}
12651172

12661173
if let Some(comment) = item.comment() {
1267-
builder = builder.with_attr(doc!(comment));
1174+
builder = builder.with_attr(attributes::doc(comment));
12681175
}
12691176

12701177
let derives =
1271-
aster::AstBuilder::new().attr().list("derive")
1272-
.words(&["Debug", "Copy", "Clone", "PartialEq", "Eq", "Hash"])
1273-
.build();
1178+
attributes::derives(&["Debug", "Copy", "Clone", "PartialEq", "Eq", "Hash"]);
1179+
12741180
builder = builder.with_attr(derives);
12751181

12761182
let mut builder = builder.enum_(&name);
@@ -1586,13 +1492,13 @@ impl CodeGenerator for Function {
15861492
let mut attributes = vec![];
15871493

15881494
if let Some(comment) = item.comment() {
1589-
attributes.push(doc!(comment));
1495+
attributes.push(attributes::doc(comment));
15901496
}
15911497

15921498
if let Some(mangled) = self.mangled_name() {
1593-
attributes.push(link_name!(mangled));
1499+
attributes.push(attributes::link_name(mangled));
15941500
} else if name != canonical_name {
1595-
attributes.push(link_name!(name));
1501+
attributes.push(attributes::link_name(name));
15961502
}
15971503

15981504
let foreign_item_kind =

0 commit comments

Comments
 (0)