Skip to content

Commit e441c20

Browse files
author
bors-servo
authored
Auto merge of rust-lang#11 - emilio:syntex, r=nox
Update syntex and use clang-sys for path-searching This is on top of rust-lang#10 because they conflicted, yet I needed clang-sys for one of the tests. r? @nox
2 parents 2396141 + 1b14b74 commit e441c20

File tree

4 files changed

+95
-133
lines changed

4 files changed

+95
-133
lines changed

Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ build = "build.rs"
1414
clippy = { version = "*", optional = true }
1515
log = "0.3.*"
1616
libc = "0.2.*"
17-
syntex_syntax = "0.32"
17+
syntex_syntax = "0.37"
18+
clang-sys = "0.7.2"
1819

1920
[features]
2021
static = []

src/bin/bindgen.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
extern crate bindgen;
55
#[macro_use]
66
extern crate log;
7+
extern crate clang_sys;
78

89
use bindgen::{Bindings, BindgenOptions, LinkType, Logger};
910
use std::io;
@@ -214,12 +215,14 @@ pub fn main() {
214215
let mut bind_args: Vec<_> = env::args().collect();
215216
let bin = bind_args.remove(0);
216217

217-
match bindgen::get_include_dir() {
218-
Some(path) => {
219-
bind_args.push("-I".to_owned());
220-
bind_args.push(path);
218+
if let Some(clang) = clang_sys::support::Clang::find(None) {
219+
// TODO: distinguish C and C++ paths? C++'s should be enough, I guess.
220+
for path in clang.cpp_search_paths.into_iter() {
221+
if let Ok(path) = path.into_os_string().into_string() {
222+
bind_args.push("-isystem".to_owned());
223+
bind_args.push(path);
224+
}
221225
}
222-
None => (),
223226
}
224227

225228
match parse_args(&bind_args) {

src/gen.rs

+82-56
Original file line numberDiff line numberDiff line change
@@ -150,21 +150,17 @@ fn enum_name(ctx: &GenCtx, name: &str) -> String {
150150
fn gen_unmangle_method(ctx: &mut GenCtx,
151151
v: &VarInfo,
152152
counts: &mut HashMap<String, isize>,
153-
self_kind: ast::SelfKind)
153+
self_kind: Option<ast::Mutability>)
154154
-> ast::ImplItem {
155-
let fndecl;
155+
let mut fndecl;
156156
let mut args = vec![];
157157

158-
match self_kind {
159-
ast::SelfKind::Static => (),
160-
ast::SelfKind::Region(_, mutable, _) => {
161-
let selfexpr = match mutable {
162-
ast::Mutability::Immutable => quote_expr!(&ctx.ext_cx, &*self),
163-
ast::Mutability::Mutable => quote_expr!(&ctx.ext_cx, &mut *self),
164-
};
165-
args.push(selfexpr);
166-
},
167-
_ => unreachable!()
158+
if let Some(mutability) = self_kind {
159+
let selfexpr = match mutability {
160+
ast::Mutability::Immutable => quote_expr!(&ctx.ext_cx, &*self),
161+
ast::Mutability::Mutable => quote_expr!(&ctx.ext_cx, &mut *self),
162+
};
163+
args.push(selfexpr);
168164
}
169165

170166
match v.ty {
@@ -173,13 +169,12 @@ fn gen_unmangle_method(ctx: &mut GenCtx,
173169
&*sig.ret_ty, sig.args.as_slice(),
174170
false);
175171
let mut unnamed: usize = 0;
176-
let iter = if args.len() > 0 {
172+
let iter = if !args.is_empty() {
177173
sig.args[1..].iter()
178174
} else {
179175
sig.args.iter()
180176
};
181-
for arg in iter {
182-
let (ref n, _) = *arg;
177+
for &(ref n, _) in iter {
183178
let argname = if n.is_empty() {
184179
unnamed += 1;
185180
format!("arg{}", unnamed)
@@ -197,46 +192,79 @@ fn gen_unmangle_method(ctx: &mut GenCtx,
197192
})
198193
}),
199194
span: ctx.span,
200-
attrs: None,
195+
attrs: ast::ThinVec::new(),
201196
};
202197
args.push(P(expr));
203198
}
204199
},
205200
_ => unreachable!()
206201
};
207202

203+
204+
if let Some(mutability) = self_kind {
205+
assert!(!fndecl.inputs.is_empty());
206+
fndecl.inputs[0] = ast::Arg {
207+
ty: P(ast::Ty {
208+
id: ast::DUMMY_NODE_ID,
209+
node: ast::TyKind::Rptr(None, ast::MutTy {
210+
ty: P(ast::Ty {
211+
id: ast::DUMMY_NODE_ID,
212+
node: ast::TyKind::ImplicitSelf,
213+
span: ctx.span
214+
}),
215+
mutbl: mutability,
216+
}),
217+
span: ctx.span,
218+
}),
219+
pat: P(ast::Pat {
220+
id: ast::DUMMY_NODE_ID,
221+
node: ast::PatKind::Ident(ast::BindingMode::ByValue(ast::Mutability::Immutable),
222+
respan(ctx.span, ctx.ext_cx.ident_of("self")),
223+
None),
224+
span: ctx.span,
225+
}),
226+
id: ast::DUMMY_NODE_ID,
227+
};
228+
}
229+
208230
let sig = ast::MethodSig {
209231
unsafety: ast::Unsafety::Unsafe,
210232
abi: Abi::Rust,
211233
decl: P(fndecl),
212234
generics: empty_generics(),
213-
explicit_self: respan(ctx.span, self_kind),
214235
constness: ast::Constness::NotConst,
215236
};
216237

217-
let block = ast::Block {
218-
stmts: vec![],
219-
expr: Some(P(ast::Expr {
220-
id: ast::DUMMY_NODE_ID,
221-
node: ast::ExprKind::Call(
222-
P(ast::Expr {
223-
id: ast::DUMMY_NODE_ID,
224-
node: ast::ExprKind::Path(None, ast::Path {
225-
span: ctx.span,
226-
global: false,
227-
segments: vec!(ast::PathSegment {
228-
identifier: ctx.ext_cx.ident_of(&v.mangled),
229-
parameters: ast::PathParameters::none()
230-
})
231-
}),
238+
let call = P(ast::Expr {
239+
id: ast::DUMMY_NODE_ID,
240+
node: ast::ExprKind::Call(
241+
P(ast::Expr {
242+
id: ast::DUMMY_NODE_ID,
243+
node: ast::ExprKind::Path(None, ast::Path {
232244
span: ctx.span,
233-
attrs: None,
245+
global: false,
246+
segments: vec![ast::PathSegment {
247+
identifier: ctx.ext_cx.ident_of(&v.mangled),
248+
parameters: ast::PathParameters::none()
249+
}]
234250
}),
235-
args
236-
),
237-
span: ctx.span,
238-
attrs: None,
239-
})),
251+
span: ctx.span,
252+
attrs: ast::ThinVec::new(),
253+
}),
254+
args
255+
),
256+
span: ctx.span,
257+
attrs: ast::ThinVec::new(),
258+
});
259+
260+
let block = ast::Block {
261+
stmts: vec![
262+
ast::Stmt {
263+
id: ast::DUMMY_NODE_ID,
264+
node: ast::StmtKind::Expr(call),
265+
span: ctx.span,
266+
}
267+
],
240268
id: ast::DUMMY_NODE_ID,
241269
rules: ast::BlockCheckMode::Default,
242270
span: ctx.span
@@ -282,16 +310,12 @@ pub fn gen_mods(links: &[(String, LinkType)],
282310
// Create a dummy ExtCtxt. We only need this for string interning and that uses TLS.
283311
let mut features = Features::new();
284312
features.quote = true;
285-
let cfg = ExpansionConfig {
286-
crate_name: "xxx".to_owned(),
287-
features: Some(&features),
288-
recursion_limit: 64,
289-
trace_mac: false,
290-
};
291-
let sess = &parse::ParseSess::new();
292-
let mut feature_gated_cfgs = vec![];
313+
314+
let cfg = ExpansionConfig::default("xxx".to_owned());
315+
let sess = parse::ParseSess::new();
316+
let mut loader = base::DummyMacroLoader;
293317
let mut ctx = GenCtx {
294-
ext_cx: base::ExtCtxt::new(sess, vec![], cfg, &mut feature_gated_cfgs),
318+
ext_cx: base::ExtCtxt::new(&sess, vec![], cfg, &mut loader),
295319
options: options,
296320
span: span,
297321
module_map: map,
@@ -1220,11 +1244,11 @@ fn cstruct_to_rs(ctx: &mut GenCtx, name: &str, ci: CompInfo) -> Vec<P<ast::Item>
12201244
TFuncPtr(ref sig) => {
12211245
let name = v.mangled.clone();
12221246
let explicit_self = if v.is_static {
1223-
ast::SelfKind::Static
1247+
None
12241248
} else if v.is_const {
1225-
ast::SelfKind::Region(None, ast::Mutability::Immutable, ctx.ext_cx.ident_of("self"))
1249+
Some(ast::Mutability::Immutable)
12261250
} else {
1227-
ast::SelfKind::Region(None, ast::Mutability::Mutable, ctx.ext_cx.ident_of("self"))
1251+
Some(ast::Mutability::Mutable)
12281252
};
12291253
unmangledlist.push(gen_unmangle_method(ctx, &v, &mut unmangle_count, explicit_self));
12301254
mangledlist.push(cfunc_to_rs(ctx, name, String::new(), String::new(),
@@ -1698,8 +1722,6 @@ fn gen_fullbitfield_method(ctx: &mut GenCtx, bindgen_name: &String,
16981722
variadic: false
16991723
};
17001724

1701-
let stmts = Vec::with_capacity(bitfields.len() + 1);
1702-
17031725
let mut offset = 0;
17041726

17051727
let mut exprs = quote_expr!(&ctx.ext_cx, 0);
@@ -1721,8 +1743,13 @@ fn gen_fullbitfield_method(ctx: &mut GenCtx, bindgen_name: &String,
17211743
}
17221744

17231745
let block = ast::Block {
1724-
stmts: stmts,
1725-
expr: Some(exprs),
1746+
stmts: vec![
1747+
ast::Stmt {
1748+
id: ast::DUMMY_NODE_ID,
1749+
node: ast::StmtKind::Expr(exprs),
1750+
span: ctx.span,
1751+
}
1752+
],
17261753
id: ast::DUMMY_NODE_ID,
17271754
rules: ast::BlockCheckMode::Default,
17281755
span: ctx.span
@@ -1734,7 +1761,6 @@ fn gen_fullbitfield_method(ctx: &mut GenCtx, bindgen_name: &String,
17341761
abi: Abi::Rust,
17351762
decl: P(fndecl),
17361763
generics: empty_generics(),
1737-
explicit_self: respan(ctx.span, ast::SelfKind::Static),
17381764
constness: ast::Constness::Const,
17391765
}, P(block)
17401766
);
@@ -2151,7 +2177,7 @@ fn mk_arrty(ctx: &GenCtx, base: &ast::Ty, n: usize) -> ast::Ty {
21512177
id: ast::DUMMY_NODE_ID,
21522178
node: sz,
21532179
span: ctx.span,
2154-
attrs: None,
2180+
attrs: ast::ThinVec::new(),
21552181
})
21562182
);
21572183

src/lib.rs

+3-71
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#![cfg_attr(feature = "clippy", plugin(clippy))]
88

99
extern crate syntex_syntax as syntax;
10+
extern crate clang_sys;
1011
extern crate libc;
1112
#[macro_use]
1213
extern crate log;
@@ -15,8 +16,7 @@ use std::collections::HashSet;
1516
use std::default::Default;
1617
use std::io::{Write, self};
1718
use std::fs::OpenOptions;
18-
use std::path::{Path, self};
19-
use std::{env, fs};
19+
use std::path::Path;
2020

2121
use syntax::ast;
2222
use syntax::codemap::{DUMMY_SP, Span};
@@ -332,8 +332,7 @@ fn builtin_names() -> HashSet<String> {
332332
}
333333

334334
#[test]
335-
fn builder_state()
336-
{
335+
fn builder_state() {
337336
let logger = DummyLogger;
338337
let mut build = builder();
339338
{
@@ -345,70 +344,3 @@ fn builder_state()
345344
assert!(build.options.clang_args.binary_search(&"example.h".to_owned()).is_ok());
346345
assert!(build.options.links.binary_search(&("m".to_owned(), LinkType::Static)).is_ok());
347346
}
348-
349-
// Get the first directory in PATH that contains a file named "clang".
350-
fn get_clang_dir() -> Option<path::PathBuf>{
351-
if let Some(paths) = env::var_os("PATH") {
352-
for mut path in env::split_paths(&paths) {
353-
path.push("clang");
354-
if let Ok(real_path) = fs::canonicalize(&path) {
355-
if fs::metadata(&real_path).iter().any(|m| m.is_file()) &&
356-
real_path
357-
.file_name()
358-
.and_then(|f| f.to_str())
359-
.iter()
360-
.any(|&f| f.starts_with("clang")) {
361-
if let Some(dir) = real_path.parent() {
362-
return Some(dir.to_path_buf())
363-
}
364-
}
365-
}
366-
}
367-
}
368-
None
369-
}
370-
371-
// Try to find the directory that contains clang's bundled headers. Clang itself does something
372-
// very similar: it takes the parent directory of the current executable, appends
373-
// "../lib/clang/<VERSIONSTRING>/include". We have two problems emulating this behaviour:
374-
// * We don't have a very good way of finding the clang executable, but can fake this by
375-
// searching $PATH and take one directory that contains "clang".
376-
// * We don't have access to <VERSIONSTRING>. There is clang_getClangVersion(), but it returns
377-
// a human-readable description string which is not guaranteed to be stable and a pain to parse.
378-
// We work around that by just taking the first directory in ../lib/clang and hope it's the
379-
// current version.
380-
// TODO: test if this works on Windows at all.
381-
#[doc(hidden)]
382-
pub fn get_include_dir() -> Option<String> {
383-
match get_clang_dir() {
384-
Some(mut p) => {
385-
p.push("..");
386-
p.push("lib");
387-
p.push("clang");
388-
389-
let dir_iter = match fs::read_dir(p) {
390-
Ok(dir_iter) => dir_iter,
391-
_ => return None
392-
};
393-
for dir in dir_iter {
394-
match dir {
395-
Ok(dir) => {
396-
// Let's take the first dir. In my case, there's only one directory
397-
// there anyway.
398-
let mut p = dir.path();
399-
p.push("include");
400-
match p.into_os_string().into_string() {
401-
Ok(s) => return Some(s),
402-
// We found the directory, but can't access it as it contains
403-
// invalid unicode.
404-
_ => return None,
405-
}
406-
}
407-
_ => return None,
408-
}
409-
}
410-
None
411-
}
412-
None => None,
413-
}
414-
}

0 commit comments

Comments
 (0)