Skip to content

Commit 79b3bb9

Browse files
committed
Merge remote-tracking branch 'servo/master' into aligned-attribute
# Conflicts: # src/ir/mod.rs
2 parents a262b68 + b10ba43 commit 79b3bb9

25 files changed

+628
-84
lines changed

.travis.yml

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ addons:
99

1010
os:
1111
- linux
12+
- osx
1213

1314
rust:
1415
- stable

ci/before_install.sh

+14-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
set -e
22
pushd ~
33

4+
# Workaround for Travis CI macOS bug (https://github.com/travis-ci/travis-ci/issues/6307)
5+
if [ "${TRAVIS_OS_NAME}" == "osx" ]; then
6+
rvm get head || true
7+
fi
8+
49
function llvm_version_triple() {
510
if [ "$1" == "3.8" ]; then
611
echo "3.8.0"
@@ -18,9 +23,17 @@ function llvm_download() {
1823
tar -xf ${LLVM}.tar.xz -C llvm --strip-components=1
1924

2025
export LLVM_CONFIG_PATH=`pwd`/llvm/bin/llvm-config
26+
if [ "${TRAVIS_OS_NAME}" == "osx" ]; then
27+
cp llvm/lib/libclang.dylib /usr/local/lib/libclang.dylib
28+
fi
2129
}
2230

23-
llvm_download linux-gnu-ubuntu-14.04
31+
32+
if [ "${TRAVIS_OS_NAME}" == "linux" ]; then
33+
llvm_download linux-gnu-ubuntu-14.04
34+
else
35+
llvm_download apple-darwin
36+
fi
2437

2538
popd
2639
set +e

src/clang.rs

+14-5
Original file line numberDiff line numberDiff line change
@@ -201,14 +201,14 @@ impl Cursor {
201201
}
202202

203203
/// Is the referent a template specialization?
204-
pub fn is_template(&self) -> bool {
204+
pub fn is_template_specialization(&self) -> bool {
205205
self.specialized().is_some()
206206
}
207207

208208
/// Is the referent a fully specialized template specialization without any
209209
/// remaining free template arguments?
210210
pub fn is_fully_specialized_template(&self) -> bool {
211-
self.is_template() && self.num_template_args().unwrap_or(0) > 0
211+
self.is_template_specialization() && self.num_template_args().unwrap_or(0) > 0
212212
}
213213

214214
/// Is the referent a template specialization that still has remaining free
@@ -217,9 +217,17 @@ impl Cursor {
217217
if self.is_toplevel() {
218218
return false;
219219
}
220+
220221
let parent = self.semantic_parent();
221-
(parent.is_template() && !parent.is_fully_specialized_template()) ||
222-
parent.is_in_non_fully_specialized_template()
222+
if parent.is_fully_specialized_template() {
223+
return false;
224+
}
225+
226+
if !parent.is_template_like() {
227+
return parent.is_in_non_fully_specialized_template();
228+
}
229+
230+
return true;
223231
}
224232

225233
/// Is this cursor pointing a valid referent?
@@ -688,7 +696,8 @@ impl Type {
688696
CXType_Pointer |
689697
CXType_RValueReference |
690698
CXType_LValueReference |
691-
CXType_MemberPointer => {
699+
CXType_MemberPointer |
700+
CXType_ObjCObjectPointer => {
692701
let ret = Type {
693702
x: unsafe { clang_getPointeeType(self.x) },
694703
};

src/codegen/mod.rs

+170-13
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use ir::item::{Item, ItemAncestors, ItemCanonicalName, ItemCanonicalPath};
1313
use ir::item_kind::ItemKind;
1414
use ir::layout::Layout;
1515
use ir::module::Module;
16+
use ir::objc::ObjCInterface;
1617
use ir::ty::{Type, TypeKind};
1718
use ir::type_collector::ItemSet;
1819
use ir::var::Var;
@@ -87,6 +88,9 @@ struct CodegenResult<'a> {
8788
/// Whether an incomplete array has been generated at least once.
8889
saw_incomplete_array: bool,
8990

91+
/// Whether Objective C types have been seen at least once.
92+
saw_objc: bool,
93+
9094
items_seen: HashSet<ItemId>,
9195
/// The set of generated function/var names, needed because in C/C++ is
9296
/// legal to do something like:
@@ -119,6 +123,7 @@ impl<'a> CodegenResult<'a> {
119123
items: vec![],
120124
saw_union: false,
121125
saw_incomplete_array: false,
126+
saw_objc: false,
122127
codegen_id: codegen_id,
123128
items_seen: Default::default(),
124129
functions_seen: Default::default(),
@@ -140,6 +145,10 @@ impl<'a> CodegenResult<'a> {
140145
self.saw_incomplete_array = true;
141146
}
142147

148+
fn saw_objc(&mut self) {
149+
self.saw_objc = true;
150+
}
151+
143152
fn seen(&self, item: ItemId) -> bool {
144153
self.items_seen.contains(&item)
145154
}
@@ -184,6 +193,7 @@ impl<'a> CodegenResult<'a> {
184193

185194
self.saw_union |= new.saw_union;
186195
self.saw_incomplete_array |= new.saw_incomplete_array;
196+
self.saw_objc |= new.saw_objc;
187197

188198
new.items
189199
}
@@ -359,6 +369,9 @@ impl CodeGenerator for Module {
359369
if ctx.need_bindegen_complex_type() {
360370
utils::prepend_complex_type(ctx, &mut *result);
361371
}
372+
if result.saw_objc {
373+
utils::prepend_objc_header(ctx, &mut *result);
374+
}
362375
}
363376
};
364377

@@ -514,7 +527,7 @@ impl CodeGenerator for Type {
514527
TypeKind::TemplateRef(..) |
515528
TypeKind::Function(..) |
516529
TypeKind::ResolvedTypeRef(..) |
517-
TypeKind::Named(..) => {
530+
TypeKind::Named => {
518531
// These items don't need code generation, they only need to be
519532
// converted to rust types in fields, arguments, and such.
520533
return;
@@ -524,8 +537,8 @@ impl CodeGenerator for Type {
524537
}
525538
// NB: The code below will pick the correct
526539
// applicable_template_args.
527-
TypeKind::TemplateAlias(ref spelling, inner, _) |
528-
TypeKind::Alias(ref spelling, inner) => {
540+
TypeKind::TemplateAlias(inner, _) |
541+
TypeKind::Alias(inner) => {
529542
let inner_item = ctx.resolve_item(inner);
530543
let name = item.canonical_name(ctx);
531544

@@ -541,6 +554,7 @@ impl CodeGenerator for Type {
541554

542555
// If this is a known named type, disallow generating anything
543556
// for it too.
557+
let spelling = self.name().expect("Unnamed alias?");
544558
if utils::type_from_named(ctx, spelling, inner).is_some() {
545559
return;
546560
}
@@ -556,6 +570,26 @@ impl CodeGenerator for Type {
556570
inner_item.to_rust_ty(ctx)
557571
};
558572

573+
{
574+
// FIXME(emilio): This is a workaround to avoid generating
575+
// incorrect type aliases because of types that we haven't
576+
// been able to resolve (because, eg, they depend on a
577+
// template parameter).
578+
//
579+
// It's kind of a shame not generating them even when they
580+
// could be referenced, but we already do the same for items
581+
// with invalid template parameters, and at least this way
582+
// they can be replaced, instead of generating plain invalid
583+
// code.
584+
let inner_canon_type =
585+
inner_item.expect_type().canonical_type(ctx);
586+
if inner_canon_type.is_invalid_named_type() {
587+
warn!("Item contained invalid named type, skipping: \
588+
{:?}, {:?}", item, inner_item);
589+
return;
590+
}
591+
}
592+
559593
let rust_name = ctx.rust_ident(&name);
560594
let mut typedef = aster::AstBuilder::new().item().pub_();
561595

@@ -593,9 +627,8 @@ impl CodeGenerator for Type {
593627
for template_arg in applicable_template_args.iter() {
594628
let template_arg = ctx.resolve_type(*template_arg);
595629
if template_arg.is_named() {
596-
let name = template_arg.name().unwrap();
597-
if name.contains("typename ") {
598-
warn!("Item contained `typename`'d template \
630+
if template_arg.is_invalid_named_type() {
631+
warn!("Item contained invalid template \
599632
parameter: {:?}", item);
600633
return;
601634
}
@@ -610,6 +643,9 @@ impl CodeGenerator for Type {
610643
TypeKind::Enum(ref ei) => {
611644
ei.codegen(ctx, result, whitelisted_items, item)
612645
}
646+
TypeKind::ObjCInterface(ref interface) => {
647+
interface.codegen(ctx, result, whitelisted_items, item)
648+
}
613649
ref u @ TypeKind::UnresolvedTypeRef(..) => {
614650
unreachable!("Should have been resolved after parsing {:?}!", u)
615651
}
@@ -2040,14 +2076,15 @@ impl ToRustTy for Type {
20402076
P(inner_ty)
20412077
}
20422078
TypeKind::ResolvedTypeRef(inner) => inner.to_rust_ty(ctx),
2043-
TypeKind::TemplateAlias(ref spelling, inner, _) |
2044-
TypeKind::Alias(ref spelling, inner) => {
2079+
TypeKind::TemplateAlias(inner, _) |
2080+
TypeKind::Alias(inner) => {
20452081
let applicable_named_args =
20462082
item.applicable_template_args(ctx)
20472083
.into_iter()
20482084
.filter(|arg| ctx.resolve_type(*arg).is_named())
20492085
.collect::<Vec<_>>();
20502086

2087+
let spelling = self.name().expect("Unnamed alias?");
20512088
if item.is_opaque(ctx) && !applicable_named_args.is_empty() {
20522089
// Pray if there's no available layout.
20532090
let layout = self.layout(ctx).unwrap_or_else(Layout::zero);
@@ -2101,11 +2138,14 @@ impl ToRustTy for Type {
21012138
ty.to_ptr(is_const, ctx.span())
21022139
}
21032140
}
2104-
TypeKind::Named(..) => {
2141+
TypeKind::Named => {
21052142
let name = item.canonical_name(ctx);
21062143
let ident = ctx.rust_ident(&name);
21072144
quote_ty!(ctx.ext_cx(), $ident)
21082145
}
2146+
TypeKind::ObjCInterface(..) => {
2147+
quote_ty!(ctx.ext_cx(), id)
2148+
},
21092149
ref u @ TypeKind::UnresolvedTypeRef(..) => {
21102150
unreachable!("Should have been resolved after parsing {:?}!", u)
21112151
}
@@ -2139,10 +2179,22 @@ impl ToRustTy for FunctionSig {
21392179
// the array type derivation.
21402180
//
21412181
// [1]: http://c0x.coding-guidelines.com/6.7.5.3.html
2142-
let arg_ty = if let TypeKind::Array(t, _) = *arg_ty.canonical_type(ctx).kind() {
2143-
t.to_rust_ty(ctx).to_ptr(arg_ty.is_const(), ctx.span())
2144-
} else {
2145-
arg_item.to_rust_ty(ctx)
2182+
let arg_ty = match *arg_ty.canonical_type(ctx).kind() {
2183+
TypeKind::Array(t, _) => {
2184+
t.to_rust_ty(ctx).to_ptr(arg_ty.is_const(), ctx.span())
2185+
},
2186+
TypeKind::Pointer(inner) => {
2187+
let inner = ctx.resolve_item(inner);
2188+
let inner_ty = inner.expect_type();
2189+
if let TypeKind::ObjCInterface(_) = *inner_ty.canonical_type(ctx).kind() {
2190+
quote_ty!(ctx.ext_cx(), id)
2191+
} else {
2192+
arg_item.to_rust_ty(ctx)
2193+
}
2194+
},
2195+
_ => {
2196+
arg_item.to_rust_ty(ctx)
2197+
}
21462198
};
21472199

21482200
let arg_name = match *name {
@@ -2261,6 +2313,85 @@ impl CodeGenerator for Function {
22612313
}
22622314
}
22632315

2316+
impl CodeGenerator for ObjCInterface {
2317+
type Extra = Item;
2318+
fn codegen<'a>(&self,
2319+
ctx: &BindgenContext,
2320+
result: &mut CodegenResult<'a>,
2321+
_whitelisted_items: &ItemSet,
2322+
_: &Item) {
2323+
let mut impl_items = vec![];
2324+
let mut trait_items = vec![];
2325+
2326+
for method in self.methods() {
2327+
let method_name = ctx.rust_ident(method.name());
2328+
2329+
let body = quote_stmt!(ctx.ext_cx(), msg_send![self, $method_name])
2330+
.unwrap();
2331+
let block = ast::Block {
2332+
stmts: vec![body],
2333+
id: ast::DUMMY_NODE_ID,
2334+
rules: ast::BlockCheckMode::Default,
2335+
span: ctx.span(),
2336+
};
2337+
2338+
let sig = aster::AstBuilder::new()
2339+
.method_sig()
2340+
.unsafe_()
2341+
.fn_decl()
2342+
.self_()
2343+
.build(ast::SelfKind::Value(ast::Mutability::Immutable))
2344+
.build(ast::FunctionRetTy::Default(ctx.span()));
2345+
let attrs = vec![];
2346+
2347+
let impl_item = ast::ImplItem {
2348+
id: ast::DUMMY_NODE_ID,
2349+
ident: ctx.rust_ident(method.rust_name()),
2350+
vis: ast::Visibility::Inherited, // Public,
2351+
attrs: attrs.clone(),
2352+
node: ast::ImplItemKind::Method(sig.clone(), P(block)),
2353+
defaultness: ast::Defaultness::Final,
2354+
span: ctx.span(),
2355+
};
2356+
2357+
let trait_item = ast::TraitItem {
2358+
id: ast::DUMMY_NODE_ID,
2359+
ident: ctx.rust_ident(method.rust_name()),
2360+
attrs: attrs,
2361+
node: ast::TraitItemKind::Method(sig, None),
2362+
span: ctx.span(),
2363+
};
2364+
2365+
impl_items.push(impl_item);
2366+
trait_items.push(trait_item)
2367+
}
2368+
2369+
2370+
let trait_block = aster::AstBuilder::new()
2371+
.item()
2372+
.pub_()
2373+
.trait_(self.name())
2374+
.with_items(trait_items)
2375+
.build();
2376+
2377+
let ty_for_impl = quote_ty!(ctx.ext_cx(), id);
2378+
let impl_block = aster::AstBuilder::new()
2379+
.item()
2380+
.impl_()
2381+
.trait_()
2382+
.id(self.name())
2383+
.build()
2384+
.with_items(impl_items)
2385+
.build_ty(ty_for_impl);
2386+
2387+
result.push(trait_block);
2388+
result.push(impl_block);
2389+
result.saw_objc();
2390+
}
2391+
}
2392+
2393+
2394+
22642395
pub fn codegen(context: &mut BindgenContext) -> Vec<P<ast::Item>> {
22652396
context.gen(|context| {
22662397
let counter = Cell::new(0);
@@ -2294,6 +2425,32 @@ mod utils {
22942425
use syntax::ast;
22952426
use syntax::ptr::P;
22962427

2428+
2429+
pub fn prepend_objc_header(ctx: &BindgenContext,
2430+
result: &mut Vec<P<ast::Item>>) {
2431+
let use_objc = if ctx.options().objc_extern_crate {
2432+
quote_item!(ctx.ext_cx(),
2433+
use objc;
2434+
).unwrap()
2435+
} else {
2436+
quote_item!(ctx.ext_cx(),
2437+
#[macro_use]
2438+
extern crate objc;
2439+
).unwrap()
2440+
};
2441+
2442+
2443+
let id_type = quote_item!(ctx.ext_cx(),
2444+
#[allow(non_camel_case_types)]
2445+
pub type id = *mut objc::runtime::Object;
2446+
)
2447+
.unwrap();
2448+
2449+
let items = vec![use_objc, id_type];
2450+
let old_items = mem::replace(result, items);
2451+
result.extend(old_items.into_iter());
2452+
}
2453+
22972454
pub fn prepend_union_types(ctx: &BindgenContext,
22982455
result: &mut Vec<P<ast::Item>>) {
22992456
let prefix = ctx.trait_prefix();

0 commit comments

Comments
 (0)