diff options
-rw-r--r-- | .travis.yml | 57 | ||||
-rw-r--r-- | ci/before_install.sh | 39 | ||||
-rwxr-xr-x | src/bin/bindgen.rs | 12 | ||||
-rwxr-xr-x | src/clang.rs | 20 | ||||
-rw-r--r-- | src/ir/context.rs | 8 | ||||
-rw-r--r-- | src/ir/item.rs | 24 | ||||
-rwxr-xr-x | src/lib.rs | 27 |
7 files changed, 109 insertions, 78 deletions
diff --git a/.travis.yml b/.travis.yml index 5d3395e5..28ffd0d7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,52 +1,39 @@ language: rust + addons: - apt: - sources: - - llvm-toolchain-precise-3.8 - - ubuntu-toolchain-r-test - packages: - - libclang-3.8-dev - - llvm-3.8-dev -env: - - LLVM_VERSION=3.8 + apt: + sources: + - ubuntu-toolchain-r-test + packages: + - gcc-5 + +os: + - linux + - osx + rust: - stable - nightly + +env: + - LLVM_VERSION=3.8 BINDGEN_FEATURES=llvm_stable + - LLVM_VERSION=3.9 BINDGEN_FEATURES= + cache: directories: - $HOME/.cargo -before_install: - - - if [ "${TRAVIS_OS_NAME}" = "osx" ]; then - if [ "${LLVM_VERSION}" != "devtools" ]; then - brew update >/dev/null; - brew install llvm3${LLVM_VERSION#3.}; - fi - fi - -before_script: - - - if [ "${TRAVIS_OS_NAME}" = "linux" ]; then - export LIBCLANG_PATH=/usr/lib/llvm-${LLVM_VERSION}/lib; - elif [ "${TRAVIS_OS_NAME}" = "osx" ]; then - if [ "${LLVM_VERSION}" = "devtools" ]; then - export LIBCLANG_PATH=/Library/Developer/CommandLineTools/usr/lib; - else - export LIBCLANG_PATH=`brew --prefix llvm3${LLVM_VERSION#3.}`/lib/llvm-${LLVM_VERSION}/lib; - fi - fi - - echo $LIBCLANG_PATH +before_install: . ./ci/before_install.sh script: - - cargo build --verbose --features llvm_stable - - cargo test --features llvm_stable - - cargo build --release --verbose --features llvm_stable - - cargo test --release --features llvm_stable + - cargo build --verbose --features "$BINDGEN_FEATURES" + - cargo test --features "$BINDGEN_FEATURES" + - cargo build --release --verbose --features "$BINDGEN_FEATURES" + - cargo test --release --features "$BINDGEN_FEATURES" - git add -A - git diff @ - git diff-index --quiet HEAD - - cargo build --features "llvm_stable _docs" + - cargo build --features "$BINDGEN_FEATURES _docs" notifications: webhooks: http://build.servo.org:54856/travis diff --git a/ci/before_install.sh b/ci/before_install.sh new file mode 100644 index 00000000..ebe4f4fb --- /dev/null +++ b/ci/before_install.sh @@ -0,0 +1,39 @@ +set -e +pushd ~ + +# Workaround for Travis CI macOS bug (https://github.com/travis-ci/travis-ci/issues/6307) +if [ "${TRAVIS_OS_NAME}" == "osx" ]; then + rvm get head || true +fi + +function llvm_version_triple() { + if [ "$1" == "3.8" ]; then + echo "3.8.0" + elif [ "$1" == "3.9" ]; then + echo "3.9.0" + fi +} + +function llvm_download() { + export LLVM_VERSION_TRIPLE=`llvm_version_triple ${LLVM_VERSION}` + export LLVM=clang+llvm-${LLVM_VERSION_TRIPLE}-x86_64-$1 + + wget http://llvm.org/releases/${LLVM_VERSION_TRIPLE}/${LLVM}.tar.xz + mkdir llvm + tar -xf ${LLVM}.tar.xz -C llvm --strip-components=1 + + export LLVM_CONFIG_PATH=`pwd`/llvm/bin/llvm-config + if [ "${TRAVIS_OS_NAME}" == "osx" ]; then + cp llvm/lib/libclang.dylib /usr/local/lib/libclang.dylib + fi +} + + +if [ "${TRAVIS_OS_NAME}" == "linux" ]; then + llvm_download linux-gnu-ubuntu-14.04 +else + llvm_download apple-darwin +fi + +popd +set +e diff --git a/src/bin/bindgen.rs b/src/bin/bindgen.rs index 2127ea49..c906efee 100755 --- a/src/bin/bindgen.rs +++ b/src/bin/bindgen.rs @@ -8,7 +8,7 @@ extern crate log; extern crate clang_sys; extern crate rustc_serialize; -use bindgen::{BindgenOptions, Bindings, LinkType, ClangVersion, clang_version}; +use bindgen::{BindgenOptions, Bindings, ClangVersion, LinkType, clang_version}; use std::default::Default; use std::env; use std::fs; @@ -233,14 +233,20 @@ pub fn main() { let mut bind_args: Vec<_> = env::args().collect(); let version = clang_version(); - let expected_version = if cfg!(feature = "llvm_stable") { (3,8) } else { (3,9) }; + let expected_version = if cfg!(feature = "llvm_stable") { + (3, 8) + } else { + (3, 9) + }; info!("Clang Version: {}", version.full); match version.parsed { None => warn!("Couldn't parse libclang version"), Some(version) if version != expected_version => { - error!("Using clang {:?}, expected {:?}", version, expected_version); + error!("Using clang {:?}, expected {:?}", + version, + expected_version); } _ => {} } diff --git a/src/clang.rs b/src/clang.rs index 11fe51d0..a84eaaab 100755 --- a/src/clang.rs +++ b/src/clang.rs @@ -249,11 +249,13 @@ impl Cursor { /// Given that this cursor's referent is a reference to another type, or is /// a declaration, get the cursor pointing to the referenced type or type of /// the declared thing. - pub fn definition(&self) -> Cursor { + pub fn definition(&self) -> Option<Cursor> { unsafe { - Cursor { + let ret = Cursor { x: clang_getCursorDefinition(self.x), - } + }; + + if ret.is_valid() { Some(ret) } else { None } } } @@ -285,7 +287,7 @@ impl Cursor { pub fn specialized(&self) -> Option<Cursor> { unsafe { let ret = Cursor { - x: clang_getSpecializedCursorTemplate(self.x) + x: clang_getSpecializedCursorTemplate(self.x), }; if ret.is_valid() { Some(ret) } else { None } } @@ -401,16 +403,6 @@ impl Cursor { } /// Given that this cursor's referent is a function/method call or - /// declaration, return a cursor to its return type. - pub fn ret_type(&self) -> Type { - unsafe { - Type { - x: clang_getCursorResultType(self.x), - } - } - } - - /// Given that this cursor's referent is a function/method call or /// declaration, return the number of arguments it takes. /// /// Returns -1 if the cursor's referent is not a function/method call or diff --git a/src/ir/context.rs b/src/ir/context.rs index c5c321c4..fc06375c 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -505,9 +505,15 @@ impl<'ctx> BindgenContext<'ctx> { found_invalid_template_ref = true; } if c.kind() == CXCursor_TypeRef { + // The `with_id` id will potentially end up unused if we give up + // on this type (for example, its a tricky partial template + // specialization), so if we pass `with_id` as the parent, it is + // potentially a dangling reference. Instead, use the canonical + // template declaration as the parent. It is already parsed and + // has a known-resolvable `ItemId`. let new_ty = Item::from_ty_or_ref(c.cur_type(), Some(c), - Some(with_id), + Some(wrapping), self); args.push(new_ty); } diff --git a/src/ir/item.rs b/src/ir/item.rs index 23090739..a07ee1f3 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -49,7 +49,9 @@ pub trait ItemCanonicalPath { /// up to (but not including) the implicit root module. pub trait ItemAncestors { /// Get an iterable over this item's ancestors. - fn ancestors<'a, 'b>(&self, ctx: &'a BindgenContext<'b>) -> ItemAncestorsIter<'a, 'b>; + fn ancestors<'a, 'b>(&self, + ctx: &'a BindgenContext<'b>) + -> ItemAncestorsIter<'a, 'b>; } /// An iterator over an item and its ancestors. @@ -86,7 +88,8 @@ impl ItemId { /// Allocate the next `ItemId`. pub fn next() -> Self { static NEXT_ITEM_ID: AtomicUsize = ATOMIC_USIZE_INIT; - ItemId(NEXT_ITEM_ID.fetch_add(1, Ordering::Relaxed)) + let next_id = NEXT_ITEM_ID.fetch_add(1, Ordering::Relaxed); + ItemId(next_id) } } @@ -799,12 +802,7 @@ impl ClangItemParser for Item { // Types are sort of special, so to avoid parsing template classes // twice, handle them separately. { - let definition = cursor.definition(); - let applicable_cursor = if definition.is_valid() { - definition - } else { - cursor - }; + let applicable_cursor = cursor.definition().unwrap_or(cursor); match Self::from_ty(&applicable_cursor.cur_type(), Some(applicable_cursor), parent_id, @@ -823,6 +821,9 @@ impl ClangItemParser for Item { // too noisy about this. match cursor.kind() { CXCursor_MacroDefinition | + CXCursor_MacroExpansion | + CXCursor_UsingDeclaration | + CXCursor_StaticAssert | CXCursor_InclusionDirective => { debug!("Unhandled cursor kind {:?}: {:?}", cursor.kind(), @@ -935,12 +936,7 @@ impl ClangItemParser for Item { let decl = { let decl = ty.declaration(); - let definition = decl.definition(); - if definition.is_valid() { - definition - } else { - decl - } + decl.definition().unwrap_or(decl) }; let comment = decl.raw_comment() @@ -496,7 +496,7 @@ fn parse(context: &mut BindgenContext) { #[derive(Debug)] pub struct ClangVersion { /// Major and minor semvar, if parsing was successful - pub parsed: Option<(u32,u32)>, + pub parsed: Option<(u32, u32)>, /// full version string pub full: String, } @@ -504,8 +504,7 @@ pub struct ClangVersion { /// Get the major and the minor semvar numbers of Clang's version pub fn clang_version() -> ClangVersion { let raw_v: String = clang::extract_clang_version(); - let split_v: Option<Vec<&str>> = raw_v - .split_whitespace() + let split_v: Option<Vec<&str>> = raw_v.split_whitespace() .nth(2) .map(|v| v.split('.').collect()); match split_v { @@ -513,15 +512,21 @@ pub fn clang_version() -> ClangVersion { if v.len() >= 2 { let maybe_major = v[0].parse::<u32>(); let maybe_minor = v[1].parse::<u32>(); - match (maybe_major,maybe_minor) { - (Ok(major),Ok(minor)) => return ClangVersion { parsed: Some((major,minor)), full: raw_v.clone() }, - _ => {}, + match (maybe_major, maybe_minor) { + (Ok(major), Ok(minor)) => { + return ClangVersion { + parsed: Some((major, minor)), + full: raw_v.clone(), + } + } + _ => {} } } - }, - None => {}, + } + None => {} }; - ClangVersion { parsed: None, full: raw_v.clone() } + ClangVersion { + parsed: None, + full: raw_v.clone(), + } } - - |