No bug - Revendor rust dependencies
authorServo VCS Sync <servo-vcs-sync@mozilla.com>
Sun, 21 May 2017 06:13:11 +0000
changeset 359796 fdf1b68b652fd195ca01a21d37274f9ee64722e6
parent 359795 e3efc7fb48dfc56b7f82ee5cfc4c316c6c60a0bf
child 359797 0665f9f01eb2afa3494edbd4b96f65320695044f
push id31857
push userphilringnalda@gmail.com
push dateSun, 21 May 2017 20:00:29 +0000
treeherdermozilla-central@cf9f9525e4d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
No bug - Revendor rust dependencies
third_party/rust/bindgen/.cargo-checksum.json
third_party/rust/bindgen/.github/ISSUE_TEMPLATE.md
third_party/rust/bindgen/Cargo.toml
third_party/rust/bindgen/ci/test.sh
third_party/rust/bindgen/src/codegen/mod.rs
third_party/rust/bindgen/src/codegen/struct_layout.rs
third_party/rust/bindgen/src/ir/comp.rs
third_party/rust/bindgen/src/ir/context.rs
third_party/rust/bindgen/src/ir/dot.rs
third_party/rust/bindgen/src/ir/item.rs
third_party/rust/bindgen/src/ir/template.rs
third_party/rust/bindgen/src/ir/ty.rs
third_party/rust/bindgen/src/lib.rs
third_party/rust/clang-sys/.cargo-checksum.json
third_party/rust/clang-sys/CHANGELOG.md
third_party/rust/clang-sys/Cargo.toml
third_party/rust/clang-sys/README.md
third_party/rust/clang-sys/build.rs
third_party/rust/peeking_take_while/.cargo-checksum.json
third_party/rust/peeking_take_while/.cargo-ok
third_party/rust/peeking_take_while/.gitignore
third_party/rust/peeking_take_while/.travis.yml
third_party/rust/peeking_take_while/Cargo.toml
third_party/rust/peeking_take_while/LICENSE-APACHE
third_party/rust/peeking_take_while/LICENSE-MIT
third_party/rust/peeking_take_while/README.md
third_party/rust/peeking_take_while/src/lib.rs
toolkit/library/gtest/rust/Cargo.lock
toolkit/library/rust/Cargo.lock
--- a/third_party/rust/bindgen/.cargo-checksum.json
+++ b/third_party/rust/bindgen/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".github/ISSUE_TEMPLATE.md":"0e894c174dc24acfc0a20439f7c0d700fcc2fc81b4c1aea00a259c3dc7ab44fb",".gitignore":"f83c74c38844f7e2adaf3f030f24945cf0f22e027b0bbf13fffb0057d6bf7ebf",".travis.yml":"5cb7111daf589d0379e3cd7c799cec2e6408f310765be81db549a1808cde6046","CONTRIBUTING.md":"113197274ed6ca925acf05330d9bae11141bc8e2ab11ae497697fa04df76f33e","Cargo.toml":"ca8088d86e128d0b4977bb8a268a6782632bde54d912fc98ff71d8bf8ab7aaa3","LICENSE":"1d2e4bdb9d94ab020e9550136cae9ec73fc699c3c96a9d98078c542e9b93d294","README.md":"a9de10e2422217cb41cac812694eedc82c2c429d18721af05a38f4593d56347c","book/.gitignore":"3c4dbff9eeda9410a0b9eb423472981db8997d666388b4cd2424700c3974d64b","book/book.toml":"dbf931141036d1d0eb02b326f7f5d7867dd9a8f0fc49b66b8fd97e9873c08e44","book/src/SUMMARY.md":"7bb880df58bbe6e4a6f103ce4fe4835e6499b2005db1b621d5c6ee26982a6f64","book/src/blacklisting.md":"a68424cc3643e06e83c5ea4efd5eb501dc64229ff9f4286b9a210a2376c20a9b","book/src/chapter_1.md":"cac4f4a3609ec22eb519b0e07d1d1bdc15ac3d741f29f9b97280f700b96ded66","book/src/command-line-usage.md":"9e3ae32cb5d893f1a93fc539149950bacdf43a18c694169fa45dfe8080617403","book/src/cpp.md":"6dab1a9997d2f30b69ba78c19ddefe48b7033a3ec247b573dba96b6be047e582","book/src/customizing-generated-bindings.md":"0363ca69719c5e24d624ac3adfef71445896d3ed2b7bb3689c7905e47bdd9cdd","book/src/introduction.md":"b6b0cdcf67ad428f53b667449e309712c617b80fade6afcf598bc58dc6bf58fa","book/src/library-usage.md":"62565cf21a6b07a9de9a3f525427e75aa0f05350a1f546ed428c8a6c40cf850c","book/src/nocopy.md":"615f9b2ae474adf32ddf49e2f29f019f857db0fbb3232ed30df3960edd9f3406","book/src/opaque.md":"d6a5d6b7dfad4e8e1f7a1307f57a0a4b723032970bbae0e1290e1ab81e08b21a","book/src/replacing-types.md":"f406f7135299cd4e67a017237a6a9acbe936aa48f37b7f52be2769c90537b73f","book/src/requirements.md":"23c71db101ccce73b46a0273fa81bc4cb1f2271499fb15f7c7befd8c95ec3bbe","book/src/tutorial-0.md":"4f46c7f76056231f8c4dc7e21dc06d7adad44b4e25a44c46c821684df023bd24","book/src/tutorial-1.md":"e6e6bb4dbdcf968d516a2da039a57f6153a21bd67167d709dc2abc6614372b1e","book/src/tutorial-2.md":"f6c9cf4ea8e38628c15dedc0ee7f60055a2aa841e95f972465d2932bb71878ad","book/src/tutorial-3.md":"112eb7ae1a1194cd82890ca3301beb309b0fa5f1ca2942db5af25f2654b06b1b","book/src/tutorial-4.md":"840edccb116f59229a2132041b5ec532f903ca90ec9904a3d1b6847779e62a66","book/src/tutorial-5.md":"45a3034e2ad8d701a8cc5d2e5e34fb427486f1ebddeff3a91a9567a1b3b668d8","book/src/tutorial-6.md":"e92a5188366108495dc1e989a1ed77c31a71b09b4c3e48936c9445b49bcc466b","book/src/whitelisting.md":"b6913e3fc43d28f504331afe4ccc3607caad9aa88d4cb627a86bdc1e72ea0175","build.rs":"e19f3db33a88f9217acef718eda6fcb6bf33949297c9f2b2bf444ce32b279a4e","ci/assert-docs.sh":"5d8ba2280bb03b9d975d2290cf9ec8f1344dafa61a3f5e2ace763019502e4e92","ci/assert-no-diff.sh":"af208c40d412e2bce82ae9b4a4e52cae4ae0b4beef9f93eb825bf5d5346a70b2","ci/assert-rustfmt.sh":"b9c810e86ea6d71bce1d6bf8d896839cfe2c198338e042ebc744b75e83af1126","ci/before_install.sh":"51409851cf4e1dee27735461e77247c599e023259c3a57e82fa044f284ca8e87","ci/deploy-book.sh":"2dc27d6252ed0f9e5e9fd5729f6087d20c6f0901ae2a470e3436f1c324623455","ci/test-book.sh":"3b8892a6c4e1f840349d2cfadff5a5e5b7ddf28b4b11e9cafd92cfe9c8d6d8c6","ci/test.sh":"495d4d0dcb8251a6be866c7e2bd090dcb63534103926c455159a5d4a097440a7","example-graphviz-ir.png":"e1122ab33b4c80e8c9c0cf8abea404c1192f9b2eef97f5766e86103cc95d5e01","rustfmt.toml":"c4f3b593bdd634590df22aaf7b0872244d5c2169aacd0274a05e4aca4708a8d3","src/callbacks.rs":"e0d36d30adac8a4eaab64f0a9df0ab29026fcd5f5c5588bdeb2ad762e4c024ad","src/clang.rs":"b160cd41a0b80aa204c85c6fd8800d31887529ef21a21d08e32585b71ee55576","src/codegen/error.rs":"2613af1d833377fd4a70719f4a09951d9d45dc9227827b9a2a938a1bcaaea2dd","src/codegen/helpers.rs":"4bbb92c587e881466ac4d343ada69f4a7a8edea8c484cf142664dade7c150acc","src/codegen/mod.rs":"239dd32206b62d542267817b1ced2d3aca975e243e685c5458010503719b832e","src/codegen/struct_layout.rs":"c485bed7bc4e0f02cd0a5e15b5d30d7756a90ffec0417f0202ad56ddb078561f","src/extra_assertions.rs":"449549c4a7a50c3f0b06332452b2fb6c9b23f31ca8e5e1656fe6c7f21e8ef7fa","src/ir/annotations.rs":"887ad7beaa43eddd60337b67951a109c2e7f51cb8e757b35cad45f744b7ba919","src/ir/comp.rs":"d674a06f569a807f57ce659dac9145ad3a02008ad895119e3b6d0869f1797b96","src/ir/context.rs":"7b6011adacb6abe2ac5ae8155d6a67d72bbf0546d1e73b00aee62856a75c4809","src/ir/derive.rs":"8706a8e3c4ccd2135d0eb9ec8c0e02008609604bce42cad2974f3ca7d2ca7d91","src/ir/dot.rs":"412da1e6ec7259c73266c437b7d5ee898d3116c00be2edbd8a69dc847c444d94","src/ir/enum_ty.rs":"cb552126907501e78a8c98a2d107c825842a45ab3fad8b656bdaf9925d0cdfd9","src/ir/function.rs":"b86146b0a3e8089d92c86ac9695b508cdeda4d0cc8f2937a131ea627dc151acd","src/ir/int.rs":"b7bc19668ca6c7c084a3f8d1e07d5a980ee49c0c9a8882c3e72baab4ea7fa403","src/ir/item.rs":"5df3c6d331b09773555f853b7d935303470d9e9b4f4f37ce3de28347d0494619","src/ir/item_kind.rs":"64b8b5bede6dfe950ceb15da1aabf888707eeb5883df9213f05ee47797bfb84f","src/ir/layout.rs":"9676218f0f25769573eb4ba848b7a8030501fc08c28b40f13a21e4fa5ee44d4e","src/ir/mod.rs":"74631e1006639aaf13e8b251efef9788b9e80b55df5b8b1fb2c484845450a196","src/ir/module.rs":"7bd8273e7001ca3d2f084e4374e21eb9f13f087bbd901849cf617e75fb712050","src/ir/named.rs":"ac96cb1a9f4ae3e9fa6494b3d97d8f30acffa180838f8ddd1392a7c168352c2d","src/ir/objc.rs":"353be93027d74ad102ac3b0ef8754dd1258a400dcf7d361fa224fdf1ab973c56","src/ir/template.rs":"35b1e216dc4f8ef904a076cee887b165dee45318a24a71bc18c794f77fa065bb","src/ir/traversal.rs":"02f25e1cad8f8630408a5b08aa5cc1d2dc97301455ef0fbb349f9f21d1334f2a","src/ir/ty.rs":"091a25e98d8bbaccc764cd1f2698493ed87128994de1f07e2fed272e81715958","src/ir/var.rs":"8d81a8227709dbe879f9aa39b7cd6c99870d1f68cd1113be03fa34a580eef43f","src/lib.rs":"c96696a54767238d7b412a955445eb72f7ab18386b0ad3dbcfea8b478660d25a","src/log_stubs.rs":"6dfdd908b7c6453da416cf232893768f9480e551ca4add0858ef88bf71ee6ceb","src/main.rs":"fdd6a6810806fa40e6bb6001be691eeaad5439ebc462ccf1d779d20ac63d6fad","src/options.rs":"c8af158043a61a90bb11005aad9515e852a89cf758322faed2dd3ec8faa641f2","src/parse.rs":"6d88e1dcdb4e99f4f65629ce205c14e18097773bc938973f8e3849ba3bda4f79","src/regex_set.rs":"6c46877238c338e1fc6a35a8983db21f0711c979e44310975f60ad73a50fdbbc","src/uses.rs":"b46a9b540c39d23fa1c22c8b5325d00486348a2aec2464deada524a6b96ebec2"},"package":"ccaf8958532d7e570e905266ee2dc1094c3e5c3c3cfc2c299368747a30a5e654"}
\ No newline at end of file
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".github/ISSUE_TEMPLATE.md":"213c5948f132f0855d1efee494beb6fae1f010d25791c19c702982157961bc96",".gitignore":"f83c74c38844f7e2adaf3f030f24945cf0f22e027b0bbf13fffb0057d6bf7ebf",".travis.yml":"5cb7111daf589d0379e3cd7c799cec2e6408f310765be81db549a1808cde6046","CONTRIBUTING.md":"113197274ed6ca925acf05330d9bae11141bc8e2ab11ae497697fa04df76f33e","Cargo.toml":"69ab16a0990af676c19c8202ecc475f455f03445ea6a915a4935cc1ffb445be7","LICENSE":"1d2e4bdb9d94ab020e9550136cae9ec73fc699c3c96a9d98078c542e9b93d294","README.md":"a9de10e2422217cb41cac812694eedc82c2c429d18721af05a38f4593d56347c","book/.gitignore":"3c4dbff9eeda9410a0b9eb423472981db8997d666388b4cd2424700c3974d64b","book/book.toml":"dbf931141036d1d0eb02b326f7f5d7867dd9a8f0fc49b66b8fd97e9873c08e44","book/src/SUMMARY.md":"7bb880df58bbe6e4a6f103ce4fe4835e6499b2005db1b621d5c6ee26982a6f64","book/src/blacklisting.md":"a68424cc3643e06e83c5ea4efd5eb501dc64229ff9f4286b9a210a2376c20a9b","book/src/chapter_1.md":"cac4f4a3609ec22eb519b0e07d1d1bdc15ac3d741f29f9b97280f700b96ded66","book/src/command-line-usage.md":"9e3ae32cb5d893f1a93fc539149950bacdf43a18c694169fa45dfe8080617403","book/src/cpp.md":"6dab1a9997d2f30b69ba78c19ddefe48b7033a3ec247b573dba96b6be047e582","book/src/customizing-generated-bindings.md":"0363ca69719c5e24d624ac3adfef71445896d3ed2b7bb3689c7905e47bdd9cdd","book/src/introduction.md":"b6b0cdcf67ad428f53b667449e309712c617b80fade6afcf598bc58dc6bf58fa","book/src/library-usage.md":"62565cf21a6b07a9de9a3f525427e75aa0f05350a1f546ed428c8a6c40cf850c","book/src/nocopy.md":"615f9b2ae474adf32ddf49e2f29f019f857db0fbb3232ed30df3960edd9f3406","book/src/opaque.md":"d6a5d6b7dfad4e8e1f7a1307f57a0a4b723032970bbae0e1290e1ab81e08b21a","book/src/replacing-types.md":"f406f7135299cd4e67a017237a6a9acbe936aa48f37b7f52be2769c90537b73f","book/src/requirements.md":"23c71db101ccce73b46a0273fa81bc4cb1f2271499fb15f7c7befd8c95ec3bbe","book/src/tutorial-0.md":"4f46c7f76056231f8c4dc7e21dc06d7adad44b4e25a44c46c821684df023bd24","book/src/tutorial-1.md":"e6e6bb4dbdcf968d516a2da039a57f6153a21bd67167d709dc2abc6614372b1e","book/src/tutorial-2.md":"f6c9cf4ea8e38628c15dedc0ee7f60055a2aa841e95f972465d2932bb71878ad","book/src/tutorial-3.md":"112eb7ae1a1194cd82890ca3301beb309b0fa5f1ca2942db5af25f2654b06b1b","book/src/tutorial-4.md":"840edccb116f59229a2132041b5ec532f903ca90ec9904a3d1b6847779e62a66","book/src/tutorial-5.md":"45a3034e2ad8d701a8cc5d2e5e34fb427486f1ebddeff3a91a9567a1b3b668d8","book/src/tutorial-6.md":"e92a5188366108495dc1e989a1ed77c31a71b09b4c3e48936c9445b49bcc466b","book/src/whitelisting.md":"b6913e3fc43d28f504331afe4ccc3607caad9aa88d4cb627a86bdc1e72ea0175","build.rs":"e19f3db33a88f9217acef718eda6fcb6bf33949297c9f2b2bf444ce32b279a4e","ci/assert-docs.sh":"5d8ba2280bb03b9d975d2290cf9ec8f1344dafa61a3f5e2ace763019502e4e92","ci/assert-no-diff.sh":"af208c40d412e2bce82ae9b4a4e52cae4ae0b4beef9f93eb825bf5d5346a70b2","ci/assert-rustfmt.sh":"b9c810e86ea6d71bce1d6bf8d896839cfe2c198338e042ebc744b75e83af1126","ci/before_install.sh":"51409851cf4e1dee27735461e77247c599e023259c3a57e82fa044f284ca8e87","ci/deploy-book.sh":"2dc27d6252ed0f9e5e9fd5729f6087d20c6f0901ae2a470e3436f1c324623455","ci/test-book.sh":"3b8892a6c4e1f840349d2cfadff5a5e5b7ddf28b4b11e9cafd92cfe9c8d6d8c6","ci/test.sh":"6e8bb39c327dbc5c709be0e50bd288bfe27efdb5c9cdfd276f97c31a951f8ff0","example-graphviz-ir.png":"e1122ab33b4c80e8c9c0cf8abea404c1192f9b2eef97f5766e86103cc95d5e01","rustfmt.toml":"c4f3b593bdd634590df22aaf7b0872244d5c2169aacd0274a05e4aca4708a8d3","src/callbacks.rs":"e0d36d30adac8a4eaab64f0a9df0ab29026fcd5f5c5588bdeb2ad762e4c024ad","src/clang.rs":"b160cd41a0b80aa204c85c6fd8800d31887529ef21a21d08e32585b71ee55576","src/codegen/error.rs":"2613af1d833377fd4a70719f4a09951d9d45dc9227827b9a2a938a1bcaaea2dd","src/codegen/helpers.rs":"4bbb92c587e881466ac4d343ada69f4a7a8edea8c484cf142664dade7c150acc","src/codegen/mod.rs":"14faa66df26851dab9567bc7e54410113d930a801c34fbff856a044074f6386a","src/codegen/struct_layout.rs":"130cf8a2e1cb8348a13e05904af2300333b51bf72cd63f3ec696b768a4a6b52d","src/extra_assertions.rs":"449549c4a7a50c3f0b06332452b2fb6c9b23f31ca8e5e1656fe6c7f21e8ef7fa","src/ir/annotations.rs":"887ad7beaa43eddd60337b67951a109c2e7f51cb8e757b35cad45f744b7ba919","src/ir/comp.rs":"359db14fc67b3c9815690ec0d95f23de4811b6f8095d568d0726328930d09cd8","src/ir/context.rs":"9b0670cc11fdfe4e7751bd1b083c288af492a3ad02c081cbd615bc4002b88b4b","src/ir/derive.rs":"8706a8e3c4ccd2135d0eb9ec8c0e02008609604bce42cad2974f3ca7d2ca7d91","src/ir/dot.rs":"d9b60aab08949a6d597d2fe000401c021f3cfff8805cd7ad02b8f22824e4525d","src/ir/enum_ty.rs":"cb552126907501e78a8c98a2d107c825842a45ab3fad8b656bdaf9925d0cdfd9","src/ir/function.rs":"b86146b0a3e8089d92c86ac9695b508cdeda4d0cc8f2937a131ea627dc151acd","src/ir/int.rs":"b7bc19668ca6c7c084a3f8d1e07d5a980ee49c0c9a8882c3e72baab4ea7fa403","src/ir/item.rs":"e42d779600f034c25094d50bab9f2aa7f9cc0ff12f9680d616433d72deb574ae","src/ir/item_kind.rs":"64b8b5bede6dfe950ceb15da1aabf888707eeb5883df9213f05ee47797bfb84f","src/ir/layout.rs":"9676218f0f25769573eb4ba848b7a8030501fc08c28b40f13a21e4fa5ee44d4e","src/ir/mod.rs":"74631e1006639aaf13e8b251efef9788b9e80b55df5b8b1fb2c484845450a196","src/ir/module.rs":"7bd8273e7001ca3d2f084e4374e21eb9f13f087bbd901849cf617e75fb712050","src/ir/named.rs":"ac96cb1a9f4ae3e9fa6494b3d97d8f30acffa180838f8ddd1392a7c168352c2d","src/ir/objc.rs":"353be93027d74ad102ac3b0ef8754dd1258a400dcf7d361fa224fdf1ab973c56","src/ir/template.rs":"35d4202ddf15bdac6ab5085bc8bdfc0fc44e0a8650ab6e49592b72252a16ebba","src/ir/traversal.rs":"02f25e1cad8f8630408a5b08aa5cc1d2dc97301455ef0fbb349f9f21d1334f2a","src/ir/ty.rs":"283975ede4c84c6cdae3a75b7015b645fce42898fdfc0f24d47877c324cff0e2","src/ir/var.rs":"8d81a8227709dbe879f9aa39b7cd6c99870d1f68cd1113be03fa34a580eef43f","src/lib.rs":"582151beb761a1c14cca0fb3ddf805b9f216b07f5ec6dfc4fd6270e3c4a337aa","src/log_stubs.rs":"6dfdd908b7c6453da416cf232893768f9480e551ca4add0858ef88bf71ee6ceb","src/main.rs":"fdd6a6810806fa40e6bb6001be691eeaad5439ebc462ccf1d779d20ac63d6fad","src/options.rs":"c8af158043a61a90bb11005aad9515e852a89cf758322faed2dd3ec8faa641f2","src/parse.rs":"6d88e1dcdb4e99f4f65629ce205c14e18097773bc938973f8e3849ba3bda4f79","src/regex_set.rs":"6c46877238c338e1fc6a35a8983db21f0711c979e44310975f60ad73a50fdbbc","src/uses.rs":"b46a9b540c39d23fa1c22c8b5325d00486348a2aec2464deada524a6b96ebec2"},"package":"708a688675f9d2e7c73018e17f5997beacc9a5ca87a0cb60c13093915facda32"}
\ No newline at end of file
--- a/third_party/rust/bindgen/.github/ISSUE_TEMPLATE.md
+++ b/third_party/rust/bindgen/.github/ISSUE_TEMPLATE.md
@@ -1,15 +1,15 @@
 ### Input C/C++ Header
 
 ```C++
 // Insert your (minimal) C/C++ header here.
 ```
 
-### Bindgen Invokation
+### Bindgen Invocation
 
 <!-- Place either the `bindgen::Builder` or the command line flags used here. -->
 
 ```Rust
 bindgen::Builder::default()
     .header("input.h")
     .generate()
     .unwrap()
--- a/third_party/rust/bindgen/Cargo.toml
+++ b/third_party/rust/bindgen/Cargo.toml
@@ -8,17 +8,17 @@ authors = [
 description = "Automatically generates Rust FFI bindings to C and C++ libraries."
 keywords = ["bindings", "ffi", "code-generation"]
 categories = ["external-ffi-bindings", "development-tools::ffi"]
 license = "BSD-3-Clause"
 name = "bindgen"
 readme = "README.md"
 repository = "https://github.com/servo/rust-bindgen"
 documentation = "https://docs.rs/bindgen"
-version = "0.25.0"
+version = "0.25.1"
 build = "build.rs"
 
 exclude = [
   "bindgen-integration",
   "ci",
   "tests/**",
 ]
 
@@ -39,18 +39,19 @@ clap = "2"
 shlex = "0.1"
 
 [build-dependencies]
 quasi_codegen = "0.32"
 
 [dependencies]
 cexpr = "0.2"
 cfg-if = "0.1.0"
-clang-sys = { version = "0.17.0", features = ["runtime", "clang_3_9"] }
+clang-sys = { version = "0.18.0", features = ["runtime", "clang_3_9"] }
 lazy_static = "0.2.1"
+peeking_take_while = "0.1.2"
 syntex_syntax = "0.58"
 regex = "0.2"
 # This kinda sucks: https://github.com/rust-lang/cargo/issues/1982
 clap = "2"
 
 [dependencies.aster]
 features = ["with-syntex"]
 version = "0.41"
--- a/third_party/rust/bindgen/ci/test.sh
+++ b/third_party/rust/bindgen/ci/test.sh
@@ -1,13 +1,15 @@
 #!/usr/bin/env bash
 
 set -xeu
 cd "$(dirname "$0")/.."
 
+export RUST_BACKTRACE=1
+
 # Regenerate the test headers' bindings in debug and release modes, and assert
 # that we always get the expected generated bindings.
 
 cargo test --features "$BINDGEN_FEATURES"
 ./ci/assert-no-diff.sh
 
 cargo test --features "$BINDGEN_FEATURES testing_only_extra_assertions"
 ./ci/assert-no-diff.sh
--- a/third_party/rust/bindgen/src/codegen/mod.rs
+++ b/third_party/rust/bindgen/src/codegen/mod.rs
@@ -1,19 +1,21 @@
 mod error;
 mod helpers;
-mod struct_layout;
+pub mod struct_layout;
 
 use self::helpers::{BlobTyBuilder, attributes};
-use self::struct_layout::{StructLayoutTracker, bytes_from_bits_pow2};
-use self::struct_layout::{align_to, bytes_from_bits};
+use self::struct_layout::StructLayoutTracker;
+
 use aster;
+use aster::struct_field::StructFieldBuilder;
 
 use ir::annotations::FieldAccessorKind;
-use ir::comp::{Base, CompInfo, CompKind, Field, Method, MethodKind};
+use ir::comp::{Base, BitfieldUnit, Bitfield, CompInfo, CompKind, Field,
+               FieldData, FieldMethods, Method, MethodKind};
 use ir::context::{BindgenContext, ItemId};
 use ir::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault};
 use ir::dot;
 use ir::enum_ty::{Enum, EnumVariant, EnumVariantValue};
 use ir::function::{Function, FunctionSig};
 use ir::int::IntKind;
 use ir::item::{Item, ItemAncestors, ItemCanonicalName, ItemCanonicalPath,
                ItemSet};
@@ -22,17 +24,16 @@ use ir::layout::Layout;
 use ir::module::Module;
 use ir::objc::{ObjCInterface, ObjCMethod};
 use ir::template::{AsNamed, TemplateInstantiation, TemplateParameters};
 use ir::ty::{Type, TypeKind};
 use ir::var::Var;
 
 use std::borrow::Cow;
 use std::cell::Cell;
-use std::cmp;
 use std::collections::{HashSet, VecDeque};
 use std::collections::hash_map::{Entry, HashMap};
 use std::fmt::Write;
 use std::mem;
 use std::ops;
 use syntax::abi::Abi;
 use syntax::ast;
 use syntax::codemap::{Span, respan};
@@ -731,120 +732,473 @@ impl<'a> TryToRustTy for Vtable<'a> {
 
     fn try_to_rust_ty(&self,
                       ctx: &BindgenContext,
                       _: &()) -> error::Result<P<ast::Ty>> {
         Ok(aster::ty::TyBuilder::new().id(self.canonical_name(ctx)))
     }
 }
 
-struct Bitfield<'a> {
-    index: &'a mut usize,
-    fields: Vec<&'a Field>,
+impl CodeGenerator for TemplateInstantiation {
+    type Extra = Item;
+
+    fn codegen<'a>(&self,
+                   ctx: &BindgenContext,
+                   result: &mut CodegenResult<'a>,
+                   _whitelisted_items: &ItemSet,
+                   item: &Item) {
+        // Although uses of instantiations don't need code generation, and are
+        // just converted to rust types in fields, vars, etc, we take this
+        // opportunity to generate tests for their layout here.
+        if !ctx.options().layout_tests {
+            return
+        }
+
+        let layout = item.kind().expect_type().layout(ctx);
+
+        if let Some(layout) = layout {
+            let size = layout.size;
+            let align = layout.align;
+
+            let name = item.canonical_name(ctx);
+            let fn_name = format!("__bindgen_test_layout_{}_instantiation_{}",
+                                  name, item.exposed_id(ctx));
+
+            let fn_name = ctx.rust_ident_raw(&fn_name);
+
+            let prefix = ctx.trait_prefix();
+            let ident = item.to_rust_ty_or_opaque(ctx, &());
+            let size_of_expr = quote_expr!(ctx.ext_cx(),
+                                           ::$prefix::mem::size_of::<$ident>());
+            let align_of_expr = quote_expr!(ctx.ext_cx(),
+                                            ::$prefix::mem::align_of::<$ident>());
+
+            let item = quote_item!(
+                ctx.ext_cx(),
+                #[test]
+                fn $fn_name() {
+                    assert_eq!($size_of_expr, $size,
+                               concat!("Size of template specialization: ",
+                                       stringify!($ident)));
+                    assert_eq!($align_of_expr, $align,
+                               concat!("Alignment of template specialization: ",
+                                       stringify!($ident)));
+                })
+                .unwrap();
+
+            result.push(item);
+        }
+    }
+}
+
+/// Generates an infinite number of anonymous field names.
+struct AnonFieldNames(usize);
+
+impl Default for AnonFieldNames {
+    fn default() -> AnonFieldNames {
+        AnonFieldNames(0)
+    }
 }
 
-impl<'a> Bitfield<'a> {
-    fn new(index: &'a mut usize, fields: Vec<&'a Field>) -> Self {
-        Bitfield {
-            index: index,
-            fields: fields,
+impl Iterator for AnonFieldNames {
+    type Item = String;
+
+    fn next(&mut self) -> Option<String> {
+        self.0 += 1;
+        Some(format!("__bindgen_anon_{}", self.0))
+    }
+}
+
+/// Trait for implementing the code generation of a struct or union field.
+trait FieldCodegen<'a> {
+    type Extra;
+
+    fn codegen<F, M>(&self,
+                     ctx: &BindgenContext,
+                     fields_should_be_private: bool,
+                     accessor_kind: FieldAccessorKind,
+                     parent: &CompInfo,
+                     anon_field_names: &mut AnonFieldNames,
+                     result: &mut CodegenResult,
+                     struct_layout: &mut StructLayoutTracker,
+                     fields: &mut F,
+                     methods: &mut M,
+                     extra: Self::Extra)
+        where F: Extend<ast::StructField>,
+              M: Extend<ast::ImplItem>;
+}
+
+impl<'a> FieldCodegen<'a> for Field {
+    type Extra = ();
+
+    fn codegen<F, M>(&self,
+                     ctx: &BindgenContext,
+                     fields_should_be_private: bool,
+                     accessor_kind: FieldAccessorKind,
+                     parent: &CompInfo,
+                     anon_field_names: &mut AnonFieldNames,
+                     result: &mut CodegenResult,
+                     struct_layout: &mut StructLayoutTracker,
+                     fields: &mut F,
+                     methods: &mut M,
+                     _: ())
+        where F: Extend<ast::StructField>,
+              M: Extend<ast::ImplItem>
+    {
+        match *self {
+            Field::DataMember(ref data) => {
+                data.codegen(ctx,
+                             fields_should_be_private,
+                             accessor_kind,
+                             parent,
+                             anon_field_names,
+                             result,
+                             struct_layout,
+                             fields,
+                             methods,
+                             ());
+            }
+            Field::Bitfields(ref unit) => {
+                unit.codegen(ctx,
+                             fields_should_be_private,
+                             accessor_kind,
+                             parent,
+                             anon_field_names,
+                             result,
+                             struct_layout,
+                             fields,
+                             methods,
+                             ());
+            }
         }
     }
-
-    fn codegen_fields(self,
-                      ctx: &BindgenContext,
-                      parent: &CompInfo,
-                      fields: &mut Vec<ast::StructField>,
-                      methods: &mut Vec<ast::ImplItem>)
-                      -> Layout {
-        // NOTE: What follows is reverse-engineered from LLVM's
-        // lib/AST/RecordLayoutBuilder.cpp
-        //
-        // FIXME(emilio): There are some differences between Microsoft and the
-        // Itanium ABI, but we'll ignore those and stick to Itanium for now.
-        //
-        // Also, we need to handle packed bitfields and stuff.
-        // TODO(emilio): Take into account C++'s wide bitfields, and
-        // packing, sigh.
-        let mut total_size_in_bits = 0;
-        let mut max_align = 0;
-        let mut unfilled_bits_in_last_unit = 0;
-        let mut field_size_in_bits = 0;
-        *self.index += 1;
-        let mut last_field_name = format!("_bitfield_{}", self.index);
-        let mut last_field_align = 0;
-
-        // (name, mask, width, bitfield's type, bitfield's layout)
-        let mut bitfields: Vec<(&str, usize, usize, ast::Ty, Layout)> = vec![];
-
-        for field in self.fields {
-            let width = field.bitfield().unwrap() as usize;
-            let field_item = ctx.resolve_item(field.ty());
-            let field_ty_layout = field_item.kind()
-                .expect_type()
-                .layout(ctx)
-                .expect("Bitfield without layout? Gah!");
-            let field_align = field_ty_layout.align;
-
-            if field_size_in_bits != 0 &&
-               (width == 0 || width > unfilled_bits_in_last_unit) {
-                // We've finished a physical field, so flush it and its bitfields.
-                field_size_in_bits = align_to(field_size_in_bits, field_align);
-                fields.push(flush_bitfields(ctx,
+}
+
+impl<'a> FieldCodegen<'a> for FieldData {
+    type Extra = ();
+
+    fn codegen<F, M>(&self,
+                     ctx: &BindgenContext,
+                     fields_should_be_private: bool,
+                     accessor_kind: FieldAccessorKind,
+                     parent: &CompInfo,
+                     anon_field_names: &mut AnonFieldNames,
+                     result: &mut CodegenResult,
+                     struct_layout: &mut StructLayoutTracker,
+                     fields: &mut F,
+                     methods: &mut M,
+                     _: ())
+        where F: Extend<ast::StructField>,
+              M: Extend<ast::ImplItem>
+    {
+        // Bitfields are handled by `FieldCodegen` implementations for
+        // `BitfieldUnit` and `Bitfield`.
+        assert!(self.bitfield().is_none());
+
+        let field_ty = ctx.resolve_type(self.ty());
+        let ty = self.ty().to_rust_ty_or_opaque(ctx, &());
+
+        // NB: In unstable rust we use proper `union` types.
+        let ty = if parent.is_union() && !ctx.options().unstable_rust {
+            if ctx.options().enable_cxx_namespaces {
+                quote_ty!(ctx.ext_cx(), root::__BindgenUnionField<$ty>)
+            } else {
+                quote_ty!(ctx.ext_cx(), __BindgenUnionField<$ty>)
+            }
+        } else if let Some(item) =
+            field_ty.is_incomplete_array(ctx) {
+            result.saw_incomplete_array();
+
+            let inner = item.to_rust_ty_or_opaque(ctx, &());
+
+            if ctx.options().enable_cxx_namespaces {
+                quote_ty!(ctx.ext_cx(), root::__IncompleteArrayField<$inner>)
+            } else {
+                quote_ty!(ctx.ext_cx(), __IncompleteArrayField<$inner>)
+            }
+        } else {
+            ty
+        };
+
+        let mut attrs = vec![];
+        if ctx.options().generate_comments {
+            if let Some(comment) = self.comment() {
+                attrs.push(attributes::doc(comment));
+            }
+        }
+
+        let field_name = self.name()
+            .map(|name| ctx.rust_mangle(name).into_owned())
+            .unwrap_or_else(|| anon_field_names.next().unwrap());
+
+        if !parent.is_union() {
+            if let Some(padding_field) =
+                struct_layout.pad_field(&field_name, field_ty, self.offset()) {
+                fields.extend(Some(padding_field));
+            }
+        }
+
+        let is_private = self.annotations()
+            .private_fields()
+            .unwrap_or(fields_should_be_private);
+
+        let accessor_kind = self.annotations()
+            .accessor_kind()
+            .unwrap_or(accessor_kind);
+
+        let mut field = StructFieldBuilder::named(&field_name);
+
+        if !is_private {
+            field = field.pub_();
+        }
+
+        let field = field.with_attrs(attrs)
+            .build_ty(ty.clone());
+
+        fields.extend(Some(field));
+
+        // TODO: Factor the following code out, please!
+        if accessor_kind == FieldAccessorKind::None {
+            return;
+        }
+
+        let getter_name =
+            ctx.rust_ident_raw(&format!("get_{}", field_name));
+        let mutable_getter_name =
+            ctx.rust_ident_raw(&format!("get_{}_mut", field_name));
+        let field_name = ctx.rust_ident_raw(&field_name);
+
+        let accessor_methods_impl = match accessor_kind {
+            FieldAccessorKind::None => unreachable!(),
+            FieldAccessorKind::Regular => {
+                quote_item!(ctx.ext_cx(),
+                    impl X {
+                        #[inline]
+                        pub fn $getter_name(&self) -> &$ty {
+                            &self.$field_name
+                        }
+
+                        #[inline]
+                        pub fn $mutable_getter_name(&mut self) -> &mut $ty {
+                            &mut self.$field_name
+                        }
+                    }
+                )
+            }
+            FieldAccessorKind::Unsafe => {
+                quote_item!(ctx.ext_cx(),
+                    impl X {
+                        #[inline]
+                        pub unsafe fn $getter_name(&self) -> &$ty {
+                            &self.$field_name
+                        }
+
+                        #[inline]
+                        pub unsafe fn $mutable_getter_name(&mut self)
+                            -> &mut $ty {
+                            &mut self.$field_name
+                        }
+                    }
+                )
+            }
+            FieldAccessorKind::Immutable => {
+                quote_item!(ctx.ext_cx(),
+                    impl X {
+                        #[inline]
+                        pub fn $getter_name(&self) -> &$ty {
+                            &self.$field_name
+                        }
+                    }
+                )
+            }
+        };
+
+        match accessor_methods_impl.unwrap().node {
+            ast::ItemKind::Impl(_, _, _, _, _, ref items) => {
+                methods.extend(items.clone())
+            }
+            _ => unreachable!(),
+        }
+    }
+}
+
+impl BitfieldUnit {
+    /// Get the constructor name for this bitfield unit.
+    fn ctor_name(&self, ctx: &BindgenContext) -> ast::Ident {
+        let ctor_name = format!("new_bitfield_{}", self.nth());
+        ctx.ext_cx().ident_of(&ctor_name)
+    }
+
+    /// Get the initial bitfield unit constructor that just returns 0. This will
+    /// then be extended by each bitfield in the unit. See `extend_ctor_impl`
+    /// below.
+    fn initial_ctor_impl(&self,
+                         ctx: &BindgenContext,
+                         unit_field_int_ty: &P<ast::Ty>)
+                         -> P<ast::Item> {
+        let ctor_name = self.ctor_name(ctx);
+
+        // If we're generating unstable Rust, add the const.
+        let fn_prefix = if ctx.options().unstable_rust {
+            quote_tokens!(ctx.ext_cx(), pub const fn)
+        } else {
+            quote_tokens!(ctx.ext_cx(), pub fn)
+        };
+
+        quote_item!(
+            ctx.ext_cx(),
+            impl XxxUnused {
+                #[inline]
+                $fn_prefix $ctor_name() -> $unit_field_int_ty {
+                    0
+                }
+            }
+        ).unwrap()
+    }
+}
+
+impl Bitfield {
+    /// Extend an under construction bitfield unit constructor with this
+    /// bitfield. This involves two things:
+    ///
+    /// 1. Adding a parameter with this bitfield's name and its type.
+    ///
+    /// 2. Bitwise or'ing the parameter into the final value of the constructed
+    /// bitfield unit.
+    fn extend_ctor_impl(&self,
+                        ctx: &BindgenContext,
+                        parent: &CompInfo,
+                        ctor_impl: P<ast::Item>,
+                        ctor_name: &ast::Ident,
+                        unit_field_int_ty: &P<ast::Ty>)
+                        -> P<ast::Item> {
+        let items = match ctor_impl.unwrap().node {
+            ast::ItemKind::Impl(_, _, _, _, _, items) => {
+                items
+            }
+            _ => unreachable!(),
+        };
+
+        assert_eq!(items.len(), 1);
+        let (sig, body) = match items[0].node {
+            ast::ImplItemKind::Method(ref sig, ref body) => {
+                (sig, body)
+            }
+            _ => unreachable!(),
+        };
+
+        let params = sig.decl.clone().unwrap().inputs;
+        let param_name = bitfield_getter_name(ctx, parent, self.name());
+
+        let bitfield_ty_item = ctx.resolve_item(self.ty());
+        let bitfield_ty = bitfield_ty_item.expect_type();
+        let bitfield_ty_layout = bitfield_ty.layout(ctx)
+            .expect("Bitfield without layout? Gah!");
+        let bitfield_int_ty = BlobTyBuilder::new(bitfield_ty_layout).build();
+        let bitfield_ty = bitfield_ty
+            .to_rust_ty_or_opaque(ctx, bitfield_ty_item);
+
+        let offset = self.offset_into_unit();
+        let mask = self.mask();
+
+        // If we're generating unstable Rust, add the const.
+        let fn_prefix = if ctx.options().unstable_rust {
+            quote_tokens!(ctx.ext_cx(), pub const fn)
+        } else {
+            quote_tokens!(ctx.ext_cx(), pub fn)
+        };
+
+        quote_item!(
+            ctx.ext_cx(),
+            impl XxxUnused {
+                #[inline]
+                $fn_prefix $ctor_name($params $param_name : $bitfield_ty)
+                                      -> $unit_field_int_ty {
+                    let bitfield_unit_val = $body;
+                    let $param_name = $param_name
+                        as $bitfield_int_ty
+                        as $unit_field_int_ty;
+                    let mask = $mask as $unit_field_int_ty;
+                    let $param_name = ($param_name << $offset) & mask;
+                    bitfield_unit_val | $param_name
+                }
+            }
+        ).unwrap()
+    }
+}
+
+impl<'a> FieldCodegen<'a> for BitfieldUnit {
+    type Extra = ();
+
+    fn codegen<F, M>(&self,
+                     ctx: &BindgenContext,
+                     fields_should_be_private: bool,
+                     accessor_kind: FieldAccessorKind,
+                     parent: &CompInfo,
+                     anon_field_names: &mut AnonFieldNames,
+                     result: &mut CodegenResult,
+                     struct_layout: &mut StructLayoutTracker,
+                     fields: &mut F,
+                     methods: &mut M,
+                     _: ())
+        where F: Extend<ast::StructField>,
+              M: Extend<ast::ImplItem>
+    {
+        let field_ty = BlobTyBuilder::new(self.layout()).build();
+        let unit_field_name = format!("_bitfield_{}", self.nth());
+
+        let field = StructFieldBuilder::named(&unit_field_name)
+            .pub_()
+            .build_ty(field_ty.clone());
+        fields.extend(Some(field));
+
+        let unit_field_int_ty = match self.layout().size {
+            8 => quote_ty!(ctx.ext_cx(), u64),
+            4 => quote_ty!(ctx.ext_cx(), u32),
+            2 => quote_ty!(ctx.ext_cx(), u16),
+            1 => quote_ty!(ctx.ext_cx(), u8),
+            _ => {
+                // Can't generate bitfield accessors for unit sizes larget than
+                // 64 bits at the moment.
+                struct_layout.saw_bitfield_unit(self.layout());
+                return;
+            }
+        };
+
+        let ctor_name = self.ctor_name(ctx);
+        let mut ctor_impl = self.initial_ctor_impl(ctx, &unit_field_int_ty);
+
+        for bf in self.bitfields() {
+            bf.codegen(ctx,
+                       fields_should_be_private,
+                       accessor_kind,
+                       parent,
+                       anon_field_names,
+                       result,
+                       struct_layout,
+                       fields,
+                       methods,
+                       (&unit_field_name, unit_field_int_ty.clone()));
+
+            ctor_impl = bf.extend_ctor_impl(ctx,
                                             parent,
-                                            field_size_in_bits,
-                                            last_field_align,
-                                            &last_field_name,
-                                            bitfields.drain(..),
-                                            methods));
-
-                // TODO(emilio): dedup this.
-                *self.index += 1;
-                last_field_name = format!("_bitfield_{}", self.index);
-
-                // Now reset the size and the rest of stuff.
-                // unfilled_bits_in_last_unit = 0;
-                field_size_in_bits = 0;
-                last_field_align = 0;
-            }
-
-            if let Some(name) = field.name() {
-                let field_item_ty = field_item.to_rust_ty_or_opaque(ctx, &());
-                bitfields.push((name,
-                                field_size_in_bits,
-                                width,
-                                field_item_ty.unwrap(),
-                                field_ty_layout));
-            }
-
-            field_size_in_bits += width;
-            total_size_in_bits += width;
-
-            let data_size = align_to(field_size_in_bits, field_align * 8);
-
-            max_align = cmp::max(max_align, field_align);
-
-            // NB: The width here is completely, absolutely intentional.
-            last_field_align = cmp::max(last_field_align, width);
-
-            unfilled_bits_in_last_unit = data_size - field_size_in_bits;
+                                            ctor_impl,
+                                            &ctor_name,
+                                            &unit_field_int_ty);
         }
 
-        if field_size_in_bits != 0 {
-            // Flush the last physical field and its bitfields.
-            fields.push(flush_bitfields(ctx,
-                                        parent,
-                                        field_size_in_bits,
-                                        last_field_align,
-                                        &last_field_name,
-                                        bitfields.drain(..),
-                                        methods));
-        }
-
-        Layout::new(bytes_from_bits(total_size_in_bits), max_align)
+        match ctor_impl.unwrap().node {
+            ast::ItemKind::Impl(_, _, _, _, _, items) => {
+                assert_eq!(items.len(), 1);
+                methods.extend(items.into_iter());
+            },
+            _ => unreachable!(),
+        };
+
+        struct_layout.saw_bitfield_unit(self.layout());
     }
 }
 
 fn parent_has_method(ctx: &BindgenContext,
                      parent: &CompInfo,
                      name: &str)
                      -> bool {
     parent.methods().iter().any(|method| {
@@ -884,162 +1238,101 @@ fn bitfield_setter_name(ctx: &BindgenCon
 
     if parent_has_method(ctx, parent, &setter) {
         setter.push_str("_bindgen_bitfield");
     }
 
     ctx.ext_cx().ident_of(&setter)
 }
 
-/// A physical field (which is a word or byte or ...) has many logical bitfields
-/// contained within it, but not all bitfields are in the same physical field of
-/// a struct. This function creates a single physical field and flushes all the
-/// accessors for the logical `bitfields` within that physical field to the
-/// outgoing `methods`.
-fn flush_bitfields<'a, I>(ctx: &BindgenContext,
-                          parent: &CompInfo,
-                          field_size_in_bits: usize,
-                          field_align: usize,
-                          field_name: &str,
-                          bitfields: I,
-                          methods: &mut Vec<ast::ImplItem>) -> ast::StructField
-    where I: IntoIterator<Item = (&'a str, usize, usize, ast::Ty, Layout)>
-{
-    use aster::struct_field::StructFieldBuilder;
-
-    let field_layout = Layout::new(bytes_from_bits_pow2(field_size_in_bits),
-                                   bytes_from_bits_pow2(field_align));
-    let field_ty = BlobTyBuilder::new(field_layout).build();
-
-    let field = StructFieldBuilder::named(field_name)
-        .pub_()
-        .build_ty(field_ty.clone());
-
-    let field_int_ty = match field_layout.size {
-        8 => quote_ty!(ctx.ext_cx(), u64),
-        4 => quote_ty!(ctx.ext_cx(), u32),
-        2 => quote_ty!(ctx.ext_cx(), u16),
-        1 => quote_ty!(ctx.ext_cx(), u8),
-        _ => return field
-    };
-
-    for (name, offset, width, bitfield_ty, bitfield_layout) in bitfields {
+impl<'a> FieldCodegen<'a> for Bitfield {
+    type Extra = (&'a str, P<ast::Ty>);
+
+    fn codegen<F, M>(&self,
+                     ctx: &BindgenContext,
+                     _fields_should_be_private: bool,
+                     _accessor_kind: FieldAccessorKind,
+                     parent: &CompInfo,
+                     _anon_field_names: &mut AnonFieldNames,
+                     _result: &mut CodegenResult,
+                     _struct_layout: &mut StructLayoutTracker,
+                     _fields: &mut F,
+                     methods: &mut M,
+                     (unit_field_name,
+                      unit_field_int_ty): (&'a str, P<ast::Ty>))
+        where F: Extend<ast::StructField>,
+              M: Extend<ast::ImplItem>
+    {
         let prefix = ctx.trait_prefix();
-        let getter_name = bitfield_getter_name(ctx, parent, name);
-        let setter_name = bitfield_setter_name(ctx, parent, name);
-        let field_ident = ctx.ext_cx().ident_of(field_name);
-
-        let bitfield_int_ty = BlobTyBuilder::new(bitfield_layout).build();
-
-        let mask: usize = ((1usize << width) - 1usize) << offset;
+        let getter_name = bitfield_getter_name(ctx, parent, self.name());
+        let setter_name = bitfield_setter_name(ctx, parent, self.name());
+        let unit_field_ident = ctx.ext_cx().ident_of(unit_field_name);
+
+        let bitfield_ty_item = ctx.resolve_item(self.ty());
+        let bitfield_ty = bitfield_ty_item.expect_type();
+
+        let bitfield_ty_layout = bitfield_ty.layout(ctx)
+            .expect("Bitfield without layout? Gah!");
+        let bitfield_int_ty = BlobTyBuilder::new(bitfield_ty_layout).build();
+
+        let bitfield_ty = bitfield_ty.to_rust_ty_or_opaque(ctx, bitfield_ty_item);
+
+        let offset = self.offset_into_unit();
+        let mask: usize = self.mask();
 
         let impl_item = quote_item!(
             ctx.ext_cx(),
             impl XxxIgnored {
                 #[inline]
                 pub fn $getter_name(&self) -> $bitfield_ty {
-                    let mask = $mask as $field_int_ty;
-                    let field_val: $field_int_ty = unsafe {
-                        ::$prefix::mem::transmute(self.$field_ident)
+                    let mask = $mask as $unit_field_int_ty;
+                    let unit_field_val: $unit_field_int_ty = unsafe {
+                        ::$prefix::mem::transmute(self.$unit_field_ident)
                     };
-                    let val = (field_val & mask) >> $offset;
+                    let val = (unit_field_val & mask) >> $offset;
                     unsafe {
                         ::$prefix::mem::transmute(val as $bitfield_int_ty)
                     }
                 }
 
                 #[inline]
                 pub fn $setter_name(&mut self, val: $bitfield_ty) {
-                    let mask = $mask as $field_int_ty;
-                    let val = val as $bitfield_int_ty as $field_int_ty;
-
-                    let mut field_val: $field_int_ty = unsafe {
-                        ::$prefix::mem::transmute(self.$field_ident)
+                    let mask = $mask as $unit_field_int_ty;
+                    let val = val as $bitfield_int_ty as $unit_field_int_ty;
+
+                    let mut unit_field_val: $unit_field_int_ty = unsafe {
+                        ::$prefix::mem::transmute(self.$unit_field_ident)
                     };
-                    field_val &= !mask;
-                    field_val |= (val << $offset) & mask;
-
-                    self.$field_ident = unsafe {
-                        ::$prefix::mem::transmute(field_val)
+                    unit_field_val &= !mask;
+                    unit_field_val |= (val << $offset) & mask;
+
+                    self.$unit_field_ident = unsafe {
+                        ::$prefix::mem::transmute(unit_field_val)
                     };
                 }
             }
         ).unwrap();
 
         match impl_item.unwrap().node {
             ast::ItemKind::Impl(_, _, _, _, _, items) => {
                 methods.extend(items.into_iter());
             },
             _ => unreachable!(),
         };
     }
-
-    field
-}
-
-impl CodeGenerator for TemplateInstantiation {
-    type Extra = Item;
-
-    fn codegen<'a>(&self,
-                   ctx: &BindgenContext,
-                   result: &mut CodegenResult<'a>,
-                   _whitelisted_items: &ItemSet,
-                   item: &Item) {
-        // Although uses of instantiations don't need code generation, and are
-        // just converted to rust types in fields, vars, etc, we take this
-        // opportunity to generate tests for their layout here.
-        if !ctx.options().layout_tests {
-            return
-        }
-
-        let layout = item.kind().expect_type().layout(ctx);
-
-        if let Some(layout) = layout {
-            let size = layout.size;
-            let align = layout.align;
-
-            let name = item.canonical_name(ctx);
-            let fn_name = format!("__bindgen_test_layout_{}_instantiation_{}",
-                                  name,
-                                  item.id().as_usize());
-            let fn_name = ctx.rust_ident_raw(&fn_name);
-
-            let prefix = ctx.trait_prefix();
-            let ident = item.to_rust_ty_or_opaque(ctx, &());
-            let size_of_expr = quote_expr!(ctx.ext_cx(),
-                                           ::$prefix::mem::size_of::<$ident>());
-            let align_of_expr = quote_expr!(ctx.ext_cx(),
-                                            ::$prefix::mem::align_of::<$ident>());
-
-            let item = quote_item!(
-                ctx.ext_cx(),
-                #[test]
-                fn $fn_name() {
-                    assert_eq!($size_of_expr, $size,
-                               concat!("Size of template specialization: ", stringify!($ident)));
-                    assert_eq!($align_of_expr, $align,
-                               concat!("Alignment of template specialization: ", stringify!($ident)));
-                })
-                .unwrap();
-
-            result.push(item);
-        }
-    }
 }
 
 impl CodeGenerator for CompInfo {
     type Extra = Item;
 
     fn codegen<'a>(&self,
                    ctx: &BindgenContext,
                    result: &mut CodegenResult<'a>,
                    whitelisted_items: &ItemSet,
                    item: &Item) {
-        use aster::struct_field::StructFieldBuilder;
-
         debug!("<CompInfo as CodeGenerator>::codegen: item = {:?}", item);
 
         // Don't output classes with template parameters that aren't types, and
         // also don't output template specializations, neither total or partial.
         if self.has_non_type_template_params() {
             return;
         }
 
@@ -1132,17 +1425,17 @@ impl CodeGenerator for CompInfo {
         //
         // FIXME: Once we generate proper vtables, we need to codegen the
         // vtable, but *not* generate a field for it in the case that
         // needs_explicit_vtable is false but has_vtable is true.
         //
         // Also, we need to generate the vtable in such a way it "inherits" from
         // the parent too.
         let mut fields = vec![];
-        let mut struct_layout = StructLayoutTracker::new(ctx, self);
+        let mut struct_layout = StructLayoutTracker::new(ctx, self, &canonical_name);
         if self.needs_explicit_vtable(ctx) {
             let vtable =
                 Vtable::new(item.id(), self.methods(), self.base_members());
             vtable.codegen(ctx, result, whitelisted_items, item);
 
             let vtable_type = vtable.try_to_rust_ty(ctx, &())
                 .expect("vtable to Rust type conversion is infallible")
                 .to_ptr(true, ctx.span());
@@ -1180,228 +1473,46 @@ impl CodeGenerator for CompInfo {
                 format!("_base_{}", i)
             };
 
             struct_layout.saw_base(base_ty);
 
             let field = StructFieldBuilder::named(field_name)
                 .pub_()
                 .build_ty(inner);
-            fields.push(field);
+            fields.extend(Some(field));
         }
         if is_union {
             result.saw_union();
         }
 
         let layout = item.kind().expect_type().layout(ctx);
 
-        let mut current_bitfield_width = None;
-        let mut current_bitfield_layout: Option<Layout> = None;
-        let mut current_bitfield_fields = vec![];
-        let mut bitfield_count = 0;
-        let struct_fields = self.fields();
         let fields_should_be_private = item.annotations()
             .private_fields()
             .unwrap_or(false);
         let struct_accessor_kind = item.annotations()
             .accessor_kind()
             .unwrap_or(FieldAccessorKind::None);
 
         let mut methods = vec![];
-        let mut anonymous_field_count = 0;
-        for field in struct_fields {
-            debug_assert_eq!(current_bitfield_width.is_some(),
-                             current_bitfield_layout.is_some());
-            debug_assert_eq!(current_bitfield_width.is_some(),
-                             !current_bitfield_fields.is_empty());
-
-            let field_ty = ctx.resolve_type(field.ty());
-
-            // Try to catch a bitfield contination early.
-            if let (Some(ref mut bitfield_width), Some(width)) =
-                (current_bitfield_width, field.bitfield()) {
-                let layout = current_bitfield_layout.unwrap();
-                debug!("Testing bitfield continuation {} {} {:?}",
-                       *bitfield_width,
-                       width,
-                       layout);
-                if *bitfield_width + width <= (layout.size * 8) as u32 {
-                    *bitfield_width += width;
-                    current_bitfield_fields.push(field);
-                    continue;
-                }
-            }
-
-            // Flush the current bitfield.
-            if current_bitfield_width.is_some() {
-                debug_assert!(!current_bitfield_fields.is_empty());
-                let bitfield_fields =
-                    mem::replace(&mut current_bitfield_fields, vec![]);
-                let bitfield_layout = Bitfield::new(&mut bitfield_count,
-                                                    bitfield_fields)
-                    .codegen_fields(ctx, self, &mut fields, &mut methods);
-                struct_layout.saw_bitfield_batch(bitfield_layout);
-
-                current_bitfield_width = None;
-                current_bitfield_layout = None;
-            }
-            debug_assert!(current_bitfield_fields.is_empty());
-
-            if let Some(width) = field.bitfield() {
-                let layout = field_ty.layout(ctx)
-                    .expect("Bitfield type without layout?");
-                current_bitfield_width = Some(width);
-                current_bitfield_layout = Some(layout);
-                current_bitfield_fields.push(field);
-                continue;
-            }
-
-            let ty = field.ty().to_rust_ty_or_opaque(ctx, &());
-
-            // NB: In unstable rust we use proper `union` types.
-            let ty = if is_union && !ctx.options().unstable_rust {
-                if ctx.options().enable_cxx_namespaces {
-                    quote_ty!(ctx.ext_cx(), root::__BindgenUnionField<$ty>)
-                } else {
-                    quote_ty!(ctx.ext_cx(), __BindgenUnionField<$ty>)
-                }
-            } else if let Some(item) =
-                field_ty.is_incomplete_array(ctx) {
-                result.saw_incomplete_array();
-
-                let inner = item.to_rust_ty_or_opaque(ctx, &());
-
-                if ctx.options().enable_cxx_namespaces {
-                    quote_ty!(ctx.ext_cx(), root::__IncompleteArrayField<$inner>)
-                } else {
-                    quote_ty!(ctx.ext_cx(), __IncompleteArrayField<$inner>)
-                }
-            } else {
-                ty
-            };
-
-            let mut attrs = vec![];
-            if ctx.options().generate_comments {
-                if let Some(comment) = field.comment() {
-                    attrs.push(attributes::doc(comment));
-                }
-            }
-            let field_name = match field.name() {
-                Some(name) => ctx.rust_mangle(name).into_owned(),
-                None => {
-                    anonymous_field_count += 1;
-                    format!("__bindgen_anon_{}", anonymous_field_count)
-                }
-            };
-
-            if !is_union {
-                if let Some(padding_field) =
-                    struct_layout.pad_field(&field_name, field_ty, field.offset()) {
-                    fields.push(padding_field);
-                }
-            }
-
-            let is_private = field.annotations()
-                .private_fields()
-                .unwrap_or(fields_should_be_private);
-
-            let accessor_kind = field.annotations()
-                .accessor_kind()
-                .unwrap_or(struct_accessor_kind);
-
-            let mut field = StructFieldBuilder::named(&field_name);
-
-            if !is_private {
-                field = field.pub_();
-            }
-
-            let field = field.with_attrs(attrs)
-                .build_ty(ty.clone());
-
-            fields.push(field);
-
-            // TODO: Factor the following code out, please!
-            if accessor_kind == FieldAccessorKind::None {
-                continue;
-            }
-
-            let getter_name =
-                ctx.rust_ident_raw(&format!("get_{}", field_name));
-            let mutable_getter_name =
-                ctx.rust_ident_raw(&format!("get_{}_mut", field_name));
-            let field_name = ctx.rust_ident_raw(&field_name);
-
-            let accessor_methods_impl = match accessor_kind {
-                FieldAccessorKind::None => unreachable!(),
-                FieldAccessorKind::Regular => {
-                    quote_item!(ctx.ext_cx(),
-                        impl X {
-                            #[inline]
-                            pub fn $getter_name(&self) -> &$ty {
-                                &self.$field_name
-                            }
-
-                            #[inline]
-                            pub fn $mutable_getter_name(&mut self) -> &mut $ty {
-                                &mut self.$field_name
-                            }
-                        }
-                    )
-                }
-                FieldAccessorKind::Unsafe => {
-                    quote_item!(ctx.ext_cx(),
-                        impl X {
-                            #[inline]
-                            pub unsafe fn $getter_name(&self) -> &$ty {
-                                &self.$field_name
-                            }
-
-                            #[inline]
-                            pub unsafe fn $mutable_getter_name(&mut self)
-                                -> &mut $ty {
-                                &mut self.$field_name
-                            }
-                        }
-                    )
-                }
-                FieldAccessorKind::Immutable => {
-                    quote_item!(ctx.ext_cx(),
-                        impl X {
-                            #[inline]
-                            pub fn $getter_name(&self) -> &$ty {
-                                &self.$field_name
-                            }
-                        }
-                    )
-                }
-            };
-
-            match accessor_methods_impl.unwrap().node {
-                ast::ItemKind::Impl(_, _, _, _, _, ref items) => {
-                    methods.extend(items.clone())
-                }
-                _ => unreachable!(),
-            }
+        let mut anon_field_names = AnonFieldNames::default();
+        for field in self.fields() {
+            field.codegen(ctx,
+                          fields_should_be_private,
+                          struct_accessor_kind,
+                          self,
+                          &mut anon_field_names,
+                          result,
+                          &mut struct_layout,
+                          &mut fields,
+                          &mut methods,
+                          ());
         }
 
-        // Flush the last bitfield if any.
-        //
-        // FIXME: Reduce duplication with the loop above.
-        // FIXME: May need to pass current_bitfield_layout too.
-        if current_bitfield_width.is_some() {
-            debug_assert!(!current_bitfield_fields.is_empty());
-            let bitfield_fields = mem::replace(&mut current_bitfield_fields,
-                                               vec![]);
-            let bitfield_layout = Bitfield::new(&mut bitfield_count,
-                                                bitfield_fields)
-                .codegen_fields(ctx, self, &mut fields, &mut methods);
-            struct_layout.saw_bitfield_batch(bitfield_layout);
-        }
-        debug_assert!(current_bitfield_fields.is_empty());
-
         if is_union && !ctx.options().unstable_rust {
             let layout = layout.expect("Unable to get layout information?");
             let ty = BlobTyBuilder::new(layout).build();
             let field = StructFieldBuilder::named("bindgen_union_field")
                 .pub_()
                 .build_ty(ty);
 
             struct_layout.saw_union(layout);
@@ -1425,17 +1536,17 @@ impl CodeGenerator for CompInfo {
                 }
                 None => {
                     warn!("Opaque type without layout! Expect dragons!");
                 }
             }
         } else if !is_union && !self.is_unsized(ctx) {
             if let Some(padding_field) =
                 layout.and_then(|layout| {
-                    struct_layout.pad_struct(&canonical_name, layout)
+                    struct_layout.pad_struct(layout)
                 }) {
                 fields.push(padding_field);
             }
 
             if let Some(align_field) =
                 layout.and_then(|layout| struct_layout.align_struct(layout)) {
                 fields.push(align_field);
             }
@@ -1549,31 +1660,34 @@ impl CodeGenerator for CompInfo {
                     let should_skip_field_offset_checks = item.is_opaque(ctx) ||
                                                           too_many_base_vtables;
 
                     let check_field_offset = if should_skip_field_offset_checks {
                         None
                     } else {
                         let asserts = self.fields()
                         .iter()
-                        .filter(|field| field.bitfield().is_none())
+                        .filter_map(|field| match *field {
+                            Field::DataMember(ref f) if f.name().is_some() => Some(f),
+                            _ => None,
+                        })
                         .flat_map(|field| {
-                            field.name().and_then(|name| {
-                                field.offset().and_then(|offset| {
-                                    let field_offset = offset / 8;
-                                    let field_name = ctx.rust_ident(name);
-
-                                    quote_item!(ctx.ext_cx(),
-                                        assert_eq!(unsafe { &(*(0 as *const $type_name)).$field_name as *const _ as usize },
-                                                   $field_offset,
-                                                   concat!("Alignment of field: ", stringify!($type_name), "::", stringify!($field_name)));
-                                    )
-                                })
+                            let name = field.name().unwrap();
+                            field.offset().and_then(|offset| {
+                                let field_offset = offset / 8;
+                                let field_name = ctx.rust_ident(name);
+
+                                quote_item!(ctx.ext_cx(),
+                                    assert_eq!(unsafe { &(*(0 as *const $type_name)).$field_name as *const _ as usize },
+                                               $field_offset,
+                                               concat!("Alignment of field: ", stringify!($type_name), "::", stringify!($field_name)));
+                                )
                             })
-                        }).collect::<Vec<P<ast::Item>>>();
+                        })
+                        .collect::<Vec<P<ast::Item>>>();
 
                         Some(asserts)
                     };
 
                     let item = quote_item!(ctx.ext_cx(),
                         #[test]
                         fn $fn_name() {
                             assert_eq!($size_of_expr,
@@ -2004,18 +2118,53 @@ impl<'a> EnumBuilder<'a> {
 
                         #[inline]
                         fn bitor(self, other: Self) -> Self {
                             $rust_ty_name(self.0 | other.0)
                         }
                     }
                 )
                     .unwrap();
-
+                result.push(impl_);
+
+                let impl_ = quote_item!(ctx.ext_cx(),
+                    impl ::$prefix::ops::BitOrAssign for $rust_ty {
+                        #[inline]
+                        fn bitor_assign(&mut self, rhs: $rust_ty) {
+                            self.0 |= rhs.0;
+                        }
+                    }
+                )
+                    .unwrap();
                 result.push(impl_);
+
+                let impl_ = quote_item!(ctx.ext_cx(),
+                    impl ::$prefix::ops::BitAnd<$rust_ty> for $rust_ty {
+                        type Output = Self;
+
+                        #[inline]
+                        fn bitand(self, other: Self) -> Self {
+                            $rust_ty_name(self.0 & other.0)
+                        }
+                    }
+                )
+                    .unwrap();
+                result.push(impl_);
+
+                let impl_ = quote_item!(ctx.ext_cx(),
+                    impl ::$prefix::ops::BitAndAssign for $rust_ty {
+                        #[inline]
+                        fn bitand_assign(&mut self, rhs: $rust_ty) {
+                            self.0 &= rhs.0;
+                        }
+                    }
+                )
+                    .unwrap();
+                result.push(impl_);
+
                 aster
             }
             EnumBuilder::Consts { aster, .. } => aster,
         }
     }
 }
 
 impl CodeGenerator for Enum {
--- a/third_party/rust/bindgen/src/codegen/struct_layout.rs
+++ b/third_party/rust/bindgen/src/codegen/struct_layout.rs
@@ -9,17 +9,19 @@ use ir::context::BindgenContext;
 use ir::layout::Layout;
 use ir::ty::{Type, TypeKind};
 use std::cmp;
 use std::mem;
 
 use syntax::ast;
 
 /// Trace the layout of struct.
+#[derive(Debug)]
 pub struct StructLayoutTracker<'a, 'ctx: 'a> {
+    name: &'a str,
     ctx: &'a BindgenContext<'ctx>,
     comp: &'a CompInfo,
     latest_offset: usize,
     padding_count: usize,
     latest_field_layout: Option<Layout>,
     max_field_align: usize,
     last_field_was_bitfield: bool,
 }
@@ -33,25 +35,16 @@ pub fn align_to(size: usize, align: usiz
     let rem = size % align;
     if rem == 0 {
         return size;
     }
 
     size + align - rem
 }
 
-/// Returns the amount of bytes from a given amount of bytes, rounding up.
-pub fn bytes_from_bits(n: usize) -> usize {
-    if n % 8 == 0 {
-        return n / 8;
-    }
-
-    n / 8 + 1
-}
-
 /// Returns the lower power of two byte count that can hold at most n bits.
 pub fn bytes_from_bits_pow2(mut n: usize) -> usize {
     if n == 0 {
         return 0;
     }
 
     if n <= 8 {
         return 1;
@@ -82,77 +75,70 @@ fn test_bytes_from_bits_pow2() {
     for i in 9..17 {
         assert_eq!(bytes_from_bits_pow2(i), 2);
     }
     for i in 17..33 {
         assert_eq!(bytes_from_bits_pow2(i), 4);
     }
 }
 
-#[test]
-fn test_bytes_from_bits() {
-    assert_eq!(bytes_from_bits(0), 0);
-    for i in 1..9 {
-        assert_eq!(bytes_from_bits(i), 1);
-    }
-    for i in 9..17 {
-        assert_eq!(bytes_from_bits(i), 2);
-    }
-    for i in 17..25 {
-        assert_eq!(bytes_from_bits(i), 3);
-    }
-}
-
 impl<'a, 'ctx> StructLayoutTracker<'a, 'ctx> {
-    pub fn new(ctx: &'a BindgenContext<'ctx>, comp: &'a CompInfo) -> Self {
+    pub fn new(ctx: &'a BindgenContext<'ctx>, comp: &'a CompInfo, name: &'a str) -> Self {
         StructLayoutTracker {
+            name: name,
             ctx: ctx,
             comp: comp,
             latest_offset: 0,
             padding_count: 0,
             latest_field_layout: None,
             max_field_align: 0,
             last_field_was_bitfield: false,
         }
     }
 
     pub fn saw_vtable(&mut self) {
+        debug!("saw vtable for {}", self.name);
+
         let ptr_size = mem::size_of::<*mut ()>();
         self.latest_offset += ptr_size;
         self.latest_field_layout = Some(Layout::new(ptr_size, ptr_size));
         self.max_field_align = ptr_size;
     }
 
     pub fn saw_base(&mut self, base_ty: &Type) {
+        debug!("saw base for {}", self.name);
         if let Some(layout) = base_ty.layout(self.ctx) {
             self.align_to_latest_field(layout);
 
             self.latest_offset += self.padding_bytes(layout) + layout.size;
             self.latest_field_layout = Some(layout);
             self.max_field_align = cmp::max(self.max_field_align, layout.align);
         }
     }
 
-    pub fn saw_bitfield_batch(&mut self, layout: Layout) {
+    pub fn saw_bitfield_unit(&mut self, layout: Layout) {
+        debug!("saw bitfield unit for {}: {:?}", self.name, layout);
+
         self.align_to_latest_field(layout);
 
         self.latest_offset += layout.size;
 
         debug!("Offset: <bitfield>: {} -> {}",
                self.latest_offset - layout.size,
                self.latest_offset);
 
         self.latest_field_layout = Some(layout);
         self.last_field_was_bitfield = true;
         // NB: We intentionally don't update the max_field_align here, since our
         // bitfields code doesn't necessarily guarantee it, so we need to
         // actually generate the dummy alignment.
     }
 
     pub fn saw_union(&mut self, layout: Layout) {
+        debug!("saw union for {}: {:?}", self.name, layout);
         self.align_to_latest_field(layout);
 
         self.latest_offset += self.padding_bytes(layout) + layout.size;
         self.latest_field_layout = Some(layout);
         self.max_field_align = cmp::max(self.max_field_align, layout.align);
     }
 
     /// Add a padding field if necessary for a given new field _before_ adding
@@ -234,23 +220,22 @@ impl<'a, 'ctx> StructLayoutTracker<'a, '
         debug!("Offset: {}: {} -> {}",
                field_name,
                self.latest_offset - field_layout.size,
                self.latest_offset);
 
         padding_layout.map(|layout| self.padding_field(layout))
     }
 
-    pub fn pad_struct(&mut self,
-                      name: &str,
-                      layout: Layout)
-                      -> Option<ast::StructField> {
+    pub fn pad_struct(&mut self, layout: Layout) -> Option<ast::StructField> {
+        debug!("pad_struct:\n\tself = {:#?}\n\tlayout = {:#?}", self, layout);
+
         if layout.size < self.latest_offset {
             error!("Calculated wrong layout for {}, too more {} bytes",
-                   name,
+                   self.name,
                    self.latest_offset - layout.size);
             return None;
         }
 
         let padding_bytes = layout.size - self.latest_offset;
 
         // We always pad to get to the correct size if the struct is one of
         // those we can't align properly.
@@ -268,17 +253,17 @@ impl<'a, 'ctx> StructLayoutTracker<'a, '
             } else if self.last_field_was_bitfield ||
                                    layout.align > mem::size_of::<*mut ()>() {
                 // We've already given up on alignment here.
                 Layout::for_size(padding_bytes)
             } else {
                 Layout::new(padding_bytes, layout.align)
             };
 
-            debug!("pad bytes to struct {}, {:?}", name, layout);
+            debug!("pad bytes to struct {}, {:?}", self.name, layout);
 
             Some(self.padding_field(layout))
         } else {
             None
         }
     }
 
     pub fn align_struct(&self, layout: Layout) -> Option<ast::StructField> {
--- a/third_party/rust/bindgen/src/ir/comp.rs
+++ b/third_party/rust/bindgen/src/ir/comp.rs
@@ -1,20 +1,26 @@
 //! Compound types (unions and structs) in our intermediate representation.
 
 use super::annotations::Annotations;
 use super::context::{BindgenContext, ItemId};
 use super::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault};
+use super::dot::DotAttributes;
 use super::item::Item;
 use super::layout::Layout;
 use super::traversal::{EdgeKind, Trace, Tracer};
 use super::template::TemplateParameters;
 use clang;
+use codegen::struct_layout::{align_to, bytes_from_bits_pow2};
 use parse::{ClangItemParser, ParseError};
+use peeking_take_while::PeekableExt;
 use std::cell::Cell;
+use std::cmp;
+use std::io;
+use std::mem;
 
 /// The kind of compound type.
 #[derive(Debug, Copy, Clone, PartialEq)]
 pub enum CompKind {
     /// A struct.
     Struct,
     /// A union.
     Union,
@@ -93,117 +99,629 @@ impl Method {
     }
 
     /// Is this a const qualified method?
     pub fn is_const(&self) -> bool {
         self.is_const
     }
 }
 
+/// Methods common to the various field types.
+pub trait FieldMethods {
+    /// Get the name of this field.
+    fn name(&self) -> Option<&str>;
+
+    /// Get the type of this field.
+    fn ty(&self) -> ItemId;
+
+    /// Get the comment for this field.
+    fn comment(&self) -> Option<&str>;
+
+    /// If this is a bitfield, how many bits does it need?
+    fn bitfield(&self) -> Option<u32>;
+
+    /// Is this field marked as `mutable`?
+    fn is_mutable(&self) -> bool;
+
+    /// Get the annotations for this field.
+    fn annotations(&self) -> &Annotations;
+
+    /// The offset of the field (in bits)
+    fn offset(&self) -> Option<usize>;
+}
+
+/// A contiguous set of logical bitfields that live within the same physical
+/// allocation unit. See 9.2.4 [class.bit] in the C++ standard and [section
+/// 2.4.II.1 in the Itanium C++
+/// ABI](http://itanium-cxx-abi.github.io/cxx-abi/abi.html#class-types).
+#[derive(Debug)]
+pub struct BitfieldUnit {
+    nth: usize,
+    layout: Layout,
+    bitfields: Vec<Bitfield>,
+}
+
+impl BitfieldUnit {
+    /// Get the 1-based index of this bitfield unit within its containing
+    /// struct. Useful for generating a Rust struct's field name for this unit
+    /// of bitfields.
+    pub fn nth(&self) -> usize {
+        self.nth
+    }
+
+    /// Get the layout within which these bitfields reside.
+    pub fn layout(&self) -> Layout {
+        self.layout
+    }
+
+    /// Get the bitfields within this unit.
+    pub fn bitfields(&self) -> &[Bitfield] {
+        &self.bitfields
+    }
+}
+
 /// A struct representing a C++ field.
-#[derive(Clone, Debug)]
-pub struct Field {
-    /// The name of the field, empty if it's an unnamed bitfield width.
-    name: Option<String>,
-    /// The inner type.
-    ty: ItemId,
-    /// The doc comment on the field if any.
-    comment: Option<String>,
-    /// Annotations for this field, or the default.
-    annotations: Annotations,
-    /// If this field is a bitfield, and how many bits does it contain if it is.
-    bitfield: Option<u32>,
-    /// If the C++ field is marked as `mutable`
-    mutable: bool,
-    /// The offset of the field (in bits)
-    offset: Option<usize>,
+#[derive(Debug)]
+pub enum Field {
+    /// A normal data member.
+    DataMember(FieldData),
+
+    /// A physical allocation unit containing many logical bitfields.
+    Bitfields(BitfieldUnit),
 }
 
 impl Field {
-    /// Construct a new `Field`.
-    pub fn new(name: Option<String>,
-               ty: ItemId,
-               comment: Option<String>,
-               annotations: Option<Annotations>,
-               bitfield: Option<u32>,
-               mutable: bool,
-               offset: Option<usize>)
-               -> Field {
-        Field {
+    fn has_destructor(&self, ctx: &BindgenContext) -> bool {
+        match *self {
+            Field::DataMember(ref data) => ctx.resolve_type(data.ty).has_destructor(ctx),
+            // Bitfields may not be of a type that has a destructor.
+            Field::Bitfields(BitfieldUnit { .. }) => false,
+        }
+    }
+
+    /// Get this field's layout.
+    pub fn layout(&self, ctx: &BindgenContext) -> Option<Layout> {
+        match *self {
+            Field::Bitfields(BitfieldUnit { layout, ..}) => Some(layout),
+            Field::DataMember(ref data) => {
+                ctx.resolve_type(data.ty).layout(ctx)
+            }
+        }
+    }
+}
+
+impl Trace for Field {
+    type Extra = ();
+
+    fn trace<T>(&self, _: &BindgenContext, tracer: &mut T, _: &())
+        where T: Tracer,
+    {
+        match *self {
+            Field::DataMember(ref data) => {
+                tracer.visit_kind(data.ty, EdgeKind::Field);
+            }
+            Field::Bitfields(BitfieldUnit { ref bitfields, .. }) => {
+                for bf in bitfields {
+                    tracer.visit_kind(bf.ty(), EdgeKind::Field);
+                }
+            }
+        }
+    }
+}
+
+impl DotAttributes for Field {
+    fn dot_attributes<W>(&self, ctx: &BindgenContext, out: &mut W) -> io::Result<()>
+        where W: io::Write
+    {
+        match *self {
+            Field::DataMember(ref data) => {
+                data.dot_attributes(ctx, out)
+            }
+            Field::Bitfields(BitfieldUnit { layout, ref bitfields, .. }) => {
+                writeln!(out,
+                         r#"<tr>
+                              <td>bitfield unit</td>
+                              <td>
+                                <table border="0">
+                                  <tr>
+                                    <td>unit.size</td><td>{}</td>
+                                  </tr>
+                                  <tr>
+                                    <td>unit.align</td><td>{}</td>
+                                  </tr>
+                         "#,
+                         layout.size,
+                         layout.align)?;
+                for bf in bitfields {
+                    bf.dot_attributes(ctx, out)?;
+                }
+                writeln!(out, "</table></td></tr>")
+            }
+        }
+    }
+}
+
+impl DotAttributes for FieldData {
+    fn dot_attributes<W>(&self, _ctx: &BindgenContext, out: &mut W) -> io::Result<()>
+        where W: io::Write
+    {
+        writeln!(out,
+                 "<tr><td>{}</td><td>{:?}</td></tr>",
+                 self.name().unwrap_or("(anonymous)"),
+                 self.ty())
+    }
+}
+
+impl DotAttributes for Bitfield {
+    fn dot_attributes<W>(&self, _ctx: &BindgenContext, out: &mut W) -> io::Result<()>
+        where W: io::Write
+    {
+        writeln!(out,
+                 "<tr><td>{} : {}</td><td>{:?}</td></tr>",
+                 self.name(),
+                 self.width(),
+                 self.ty())
+    }
+}
+
+/// A logical bitfield within some physical bitfield allocation unit.
+#[derive(Debug)]
+pub struct Bitfield {
+    /// Index of the bit within this bitfield's allocation unit where this
+    /// bitfield's bits begin.
+    offset_into_unit: usize,
+
+    /// The field data for this bitfield.
+    data: FieldData,
+}
+
+impl Bitfield {
+    /// Construct a new bitfield.
+    fn new(offset_into_unit: usize, raw: RawField) -> Bitfield {
+        assert!(raw.bitfield().is_some());
+        assert!(raw.name().is_some());
+
+        Bitfield {
+            offset_into_unit: offset_into_unit,
+            data: raw.0,
+        }
+    }
+
+    /// Get the index of the bit within this bitfield's allocation unit where
+    /// this bitfield begins.
+    pub fn offset_into_unit(&self) -> usize {
+        self.offset_into_unit
+    }
+
+    /// Get the mask value that when &'ed with this bitfield's allocation unit
+    /// produces this bitfield's value.
+    pub fn mask(&self) -> usize {
+        ((1usize << self.width()) - 1usize) << self.offset_into_unit()
+    }
+
+    /// Get the bit width of this bitfield.
+    pub fn width(&self) -> u32 {
+        self.data.bitfield().unwrap()
+    }
+
+    /// Get the name of this bitfield.
+    pub fn name(&self) -> &str {
+        self.data.name().unwrap()
+    }
+}
+
+impl FieldMethods for Bitfield {
+    fn name(&self) -> Option<&str> {
+        self.data.name()
+    }
+
+    fn ty(&self) -> ItemId {
+        self.data.ty()
+    }
+
+    fn comment(&self) -> Option<&str> {
+        self.data.comment()
+    }
+
+    fn bitfield(&self) -> Option<u32> {
+        self.data.bitfield()
+    }
+
+    fn is_mutable(&self) -> bool {
+        self.data.is_mutable()
+    }
+
+    fn annotations(&self) -> &Annotations {
+        self.data.annotations()
+    }
+
+    fn offset(&self) -> Option<usize> {
+        self.data.offset()
+    }
+}
+
+
+/// A raw field might be either of a plain data member or a bitfield within a
+/// bitfield allocation unit, but we haven't processed it and determined which
+/// yet (which would involve allocating it into a bitfield unit if it is a
+/// bitfield).
+#[derive(Debug)]
+struct RawField(FieldData);
+
+impl RawField {
+    /// Construct a new `RawField`.
+    fn new(name: Option<String>,
+           ty: ItemId,
+           comment: Option<String>,
+           annotations: Option<Annotations>,
+           bitfield: Option<u32>,
+           mutable: bool,
+           offset: Option<usize>)
+           -> RawField {
+        RawField(FieldData {
             name: name,
             ty: ty,
             comment: comment,
             annotations: annotations.unwrap_or_default(),
             bitfield: bitfield,
             mutable: mutable,
             offset: offset,
+        })
+    }
+}
+
+impl FieldMethods for RawField {
+    fn name(&self) -> Option<&str> {
+        self.0.name()
+    }
+
+    fn ty(&self) -> ItemId {
+        self.0.ty()
+    }
+
+    fn comment(&self) -> Option<&str> {
+        self.0.comment()
+    }
+
+    fn bitfield(&self) -> Option<u32> {
+        self.0.bitfield()
+    }
+
+    fn is_mutable(&self) -> bool {
+        self.0.is_mutable()
+    }
+
+    fn annotations(&self) -> &Annotations {
+        self.0.annotations()
+    }
+
+    fn offset(&self) -> Option<usize> {
+        self.0.offset()
+    }
+}
+
+/// Convert the given ordered set of raw fields into a list of either plain data
+/// members, and/or bitfield units containing multiple bitfields.
+fn raw_fields_to_fields_and_bitfield_units<I>(ctx: &BindgenContext,
+                                              raw_fields: I)
+                                              -> Vec<Field>
+    where I: IntoIterator<Item=RawField>
+{
+    let mut raw_fields = raw_fields.into_iter().fuse().peekable();
+    let mut fields = vec![];
+    let mut bitfield_unit_count = 0;
+
+    loop {
+        // While we have plain old data members, just keep adding them to our
+        // resulting fields. We introduce a scope here so that we can use
+        // `raw_fields` again after the `by_ref` iterator adaptor is dropped.
+        {
+            let non_bitfields = raw_fields
+                .by_ref()
+                .peeking_take_while(|f| f.bitfield().is_none())
+                .map(|f| Field::DataMember(f.0));
+            fields.extend(non_bitfields);
+        }
+
+        // Now gather all the consecutive bitfields. Only consecutive bitfields
+        // may potentially share a bitfield allocation unit with each other in
+        // the Itanium C++ ABI.
+        let mut bitfields = raw_fields
+            .by_ref()
+            .peeking_take_while(|f| f.bitfield().is_some())
+            .peekable();
+
+        if bitfields.peek().is_none() {
+            break;
+        }
+
+        bitfields_to_allocation_units(ctx,
+                                      &mut bitfield_unit_count,
+                                      &mut fields,
+                                      bitfields);
+    }
+
+    assert!(raw_fields.next().is_none(),
+            "The above loop should consume all items in `raw_fields`");
+
+    fields
+}
+
+/// Given a set of contiguous raw bitfields, group and allocate them into
+/// (potentially multiple) bitfield units.
+fn bitfields_to_allocation_units<E, I>(ctx: &BindgenContext,
+                                       bitfield_unit_count: &mut usize,
+                                       mut fields: &mut E,
+                                       raw_bitfields: I)
+    where E: Extend<Field>,
+          I: IntoIterator<Item=RawField>
+{
+    assert!(ctx.collected_typerefs());
+
+    // NOTE: What follows is reverse-engineered from LLVM's
+    // lib/AST/RecordLayoutBuilder.cpp
+    //
+    // FIXME(emilio): There are some differences between Microsoft and the
+    // Itanium ABI, but we'll ignore those and stick to Itanium for now.
+    //
+    // Also, we need to handle packed bitfields and stuff.
+    //
+    // TODO(emilio): Take into account C++'s wide bitfields, and
+    // packing, sigh.
+
+    fn flush_allocation_unit<E>(mut fields: &mut E,
+                                bitfield_unit_count: &mut usize,
+                                unit_size_in_bits: usize,
+                                unit_align_in_bits: usize,
+                                bitfields: Vec<Bitfield>)
+        where E: Extend<Field>
+    {
+        *bitfield_unit_count += 1;
+        let layout = Layout::new(bytes_from_bits_pow2(unit_size_in_bits),
+                                 bytes_from_bits_pow2(unit_align_in_bits));
+        fields.extend(Some(Field::Bitfields(BitfieldUnit {
+            nth: *bitfield_unit_count,
+            layout: layout,
+            bitfields: bitfields,
+        })));
+    }
+
+    let mut max_align = 0;
+    let mut unfilled_bits_in_unit = 0;
+    let mut unit_size_in_bits = 0;
+    let mut unit_align = 0;
+    let mut bitfields_in_unit = vec![];
+
+    for bitfield in raw_bitfields {
+        let bitfield_width = bitfield.bitfield().unwrap() as usize;
+        let bitfield_align = ctx.resolve_type(bitfield.ty())
+            .layout(ctx)
+            .expect("Bitfield without layout? Gah!")
+            .align;
+
+        if unit_size_in_bits != 0 &&
+           (bitfield_width == 0 ||
+            bitfield_width > unfilled_bits_in_unit) {
+            // We've reached the end of this allocation unit, so flush it
+            // and its bitfields.
+            unit_size_in_bits = align_to(unit_size_in_bits,
+                                                 bitfield_align);
+            flush_allocation_unit(fields,
+                                  bitfield_unit_count,
+                                  unit_size_in_bits,
+                                  unit_align,
+                                  mem::replace(&mut bitfields_in_unit, vec![]));
+
+            // Now we're working on a fresh bitfield allocation unit, so reset
+            // the current unit size and alignment.
+            unit_size_in_bits = 0;
+            unit_align = 0;
+        }
+
+        // Only keep named bitfields around. Unnamed bitfields (with > 0
+        // bitsize) are used for padding. Because the `Bitfield` struct stores
+        // the bit-offset into its allocation unit where its bits begin, we
+        // don't need any padding bits hereafter.
+        if bitfield.name().is_some() {
+            bitfields_in_unit.push(Bitfield::new(unit_size_in_bits, bitfield));
+        }
+
+        unit_size_in_bits += bitfield_width;
+
+        max_align = cmp::max(max_align, bitfield_align);
+
+        // NB: The `bitfield_width` here is completely, absolutely intentional.
+        // Alignment of the allocation unit is based on the maximum bitfield
+        // width, not (directly) on the bitfields' types' alignment.
+        unit_align = cmp::max(unit_align, bitfield_width);
+
+        // Compute what the physical unit's final size would be given what we
+        // have seen so far, and use that to compute how many bits are still
+        // available in the unit.
+        let data_size = align_to(unit_size_in_bits, bitfield_align * 8);
+        unfilled_bits_in_unit = data_size - unit_size_in_bits;
+    }
+
+    if unit_size_in_bits != 0 {
+        // Flush the last allocation unit and its bitfields.
+        flush_allocation_unit(fields,
+                              bitfield_unit_count,
+                              unit_size_in_bits,
+                              unit_align,
+                              bitfields_in_unit);
+    }
+}
+
+/// A compound structure's fields are initially raw, and have bitfields that
+/// have not been grouped into allocation units. During this time, the fields
+/// are mutable and we build them up during parsing.
+///
+/// Then, once resolving typerefs is completed, we compute all structs' fields'
+/// bitfield allocation units, and they remain frozen and immutable forever
+/// after.
+#[derive(Debug)]
+enum CompFields {
+    BeforeComputingBitfieldUnits(Vec<RawField>),
+    AfterComputingBitfieldUnits(Vec<Field>),
+}
+
+impl Default for CompFields {
+    fn default() -> CompFields {
+        CompFields::BeforeComputingBitfieldUnits(vec![])
+    }
+}
+
+impl CompFields {
+    fn append_raw_field(&mut self, raw: RawField) {
+        match *self {
+            CompFields::BeforeComputingBitfieldUnits(ref mut raws) => {
+                raws.push(raw);
+            }
+            CompFields::AfterComputingBitfieldUnits(_) => {
+                panic!("Must not append new fields after computing bitfield allocation units");
+            }
         }
     }
 
-    /// Get the name of this field.
-    pub fn name(&self) -> Option<&str> {
+    fn compute_bitfield_units(&mut self, ctx: &BindgenContext) {
+        let raws = match *self {
+            CompFields::BeforeComputingBitfieldUnits(ref mut raws) => {
+                mem::replace(raws, vec![])
+            }
+            CompFields::AfterComputingBitfieldUnits(_) => {
+                panic!("Already computed bitfield units");
+            }
+        };
+
+        let fields_and_units = raw_fields_to_fields_and_bitfield_units(ctx, raws);
+        mem::replace(self, CompFields::AfterComputingBitfieldUnits(fields_and_units));
+    }
+}
+
+impl Trace for CompFields {
+    type Extra = ();
+
+    fn trace<T>(&self, context: &BindgenContext, tracer: &mut T, _: &())
+        where T: Tracer,
+    {
+        match *self {
+            CompFields::BeforeComputingBitfieldUnits(ref fields) => {
+                for f in fields {
+                    tracer.visit_kind(f.ty(), EdgeKind::Field);
+                }
+            }
+            CompFields::AfterComputingBitfieldUnits(ref fields) => {
+                for f in fields {
+                    f.trace(context, tracer, &());
+                }
+            }
+        }
+    }
+}
+
+/// Common data shared across different field types.
+#[derive(Clone, Debug)]
+pub struct FieldData {
+    /// The name of the field, empty if it's an unnamed bitfield width.
+    name: Option<String>,
+
+    /// The inner type.
+    ty: ItemId,
+
+    /// The doc comment on the field if any.
+    comment: Option<String>,
+
+    /// Annotations for this field, or the default.
+    annotations: Annotations,
+
+    /// If this field is a bitfield, and how many bits does it contain if it is.
+    bitfield: Option<u32>,
+
+    /// If the C++ field is marked as `mutable`
+    mutable: bool,
+
+    /// The offset of the field (in bits)
+    offset: Option<usize>,
+}
+
+impl FieldMethods for FieldData {
+    fn name(&self) -> Option<&str> {
         self.name.as_ref().map(|n| &**n)
     }
 
-    /// Get the type of this field.
-    pub fn ty(&self) -> ItemId {
+    fn ty(&self) -> ItemId {
         self.ty
     }
 
-    /// Get the comment for this field.
-    pub fn comment(&self) -> Option<&str> {
+    fn comment(&self) -> Option<&str> {
         self.comment.as_ref().map(|c| &**c)
     }
 
-    /// If this is a bitfield, how many bits does it need?
-    pub fn bitfield(&self) -> Option<u32> {
+    fn bitfield(&self) -> Option<u32> {
         self.bitfield
     }
 
-    /// Is this field marked as `mutable`?
-    pub fn is_mutable(&self) -> bool {
+    fn is_mutable(&self) -> bool {
         self.mutable
     }
 
-    /// Get the annotations for this field.
-    pub fn annotations(&self) -> &Annotations {
+    fn annotations(&self) -> &Annotations {
         &self.annotations
     }
 
-    /// The offset of the field (in bits)
-    pub fn offset(&self) -> Option<usize> {
+    fn offset(&self) -> Option<usize> {
         self.offset
     }
 }
 
 impl CanDeriveDebug for Field {
     type Extra = ();
 
     fn can_derive_debug(&self, ctx: &BindgenContext, _: ()) -> bool {
-        self.ty.can_derive_debug(ctx, ())
+        match *self {
+            Field::DataMember(ref data) => data.ty.can_derive_debug(ctx, ()),
+            Field::Bitfields(BitfieldUnit { ref bitfields, .. }) => bitfields.iter().all(|b| {
+                b.ty().can_derive_debug(ctx, ())
+            }),
+        }
     }
 }
 
 impl CanDeriveDefault for Field {
     type Extra = ();
 
     fn can_derive_default(&self, ctx: &BindgenContext, _: ()) -> bool {
-        self.ty.can_derive_default(ctx, ())
+        match *self {
+            Field::DataMember(ref data) => data.ty.can_derive_default(ctx, ()),
+            Field::Bitfields(BitfieldUnit { ref bitfields, .. }) => bitfields.iter().all(|b| {
+                b.ty().can_derive_default(ctx, ())
+            }),
+        }
     }
 }
 
 impl<'a> CanDeriveCopy<'a> for Field {
     type Extra = ();
 
     fn can_derive_copy(&self, ctx: &BindgenContext, _: ()) -> bool {
-        self.ty.can_derive_copy(ctx, ())
+        match *self {
+            Field::DataMember(ref data) => data.ty.can_derive_copy(ctx, ()),
+            Field::Bitfields(BitfieldUnit { ref bitfields, .. }) => bitfields.iter().all(|b| {
+                b.ty().can_derive_copy(ctx, ())
+            }),
+        }
     }
 
     fn can_derive_copy_in_array(&self, ctx: &BindgenContext, _: ()) -> bool {
-        self.ty.can_derive_copy_in_array(ctx, ())
+        match *self {
+            Field::DataMember(ref data) => data.ty.can_derive_copy_in_array(ctx, ()),
+            Field::Bitfields(BitfieldUnit { ref bitfields, .. }) => bitfields.iter().all(|b| {
+                b.ty().can_derive_copy_in_array(ctx, ())
+            }),
+        }
     }
 }
 
 
 /// The kind of inheritance a base class is using.
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub enum BaseKind {
     /// Normal inheritance, like:
@@ -242,22 +760,22 @@ impl Base {
 /// of fields which also are associated with their own (potentially compound)
 /// type.
 #[derive(Debug)]
 pub struct CompInfo {
     /// Whether this is a struct or a union.
     kind: CompKind,
 
     /// The members of this struct or union.
-    fields: Vec<Field>,
+    fields: CompFields,
 
-    /// The abstract template parameters of this class. These are NOT concrete
-    /// template arguments, and should always be a
-    /// Type(TypeKind::Named(name)). For concrete template arguments, see the
-    /// TypeKind::TemplateInstantiation.
+    /// The abstract template parameters of this class. Note that these are NOT
+    /// concrete template arguments, and should always be a
+    /// `Type(TypeKind::Named(name))`. For concrete template arguments, see
+    /// `TypeKind::TemplateInstantiation`.
     template_params: Vec<ItemId>,
 
     /// The method declarations inside this class, if in C++ mode.
     methods: Vec<Method>,
 
     /// The different constructors this struct or class contains.
     constructors: Vec<ItemId>,
 
@@ -327,17 +845,17 @@ pub struct CompInfo {
     is_forward_declaration: bool,
 }
 
 impl CompInfo {
     /// Construct a new compound type.
     pub fn new(kind: CompKind) -> Self {
         CompInfo {
             kind: kind,
-            fields: vec![],
+            fields: CompFields::default(),
             template_params: vec![],
             methods: vec![],
             constructors: vec![],
             destructor: None,
             base_members: vec![],
             inner_types: vec![],
             inner_vars: vec![],
             has_vtable: false,
@@ -350,17 +868,17 @@ impl CompInfo {
             detect_derive_default_cycle: Cell::new(false),
             detect_has_destructor_cycle: Cell::new(false),
             is_forward_declaration: false,
         }
     }
 
     /// Is this compound type unsized?
     pub fn is_unsized(&self, ctx: &BindgenContext) -> bool {
-        !self.has_vtable(ctx) && self.fields.is_empty() &&
+        !self.has_vtable(ctx) && self.fields().is_empty() &&
         self.base_members.iter().all(|base| {
             ctx.resolve_type(base.ty).canonical_type(ctx).is_unsized(ctx)
         })
     }
 
     /// Does this compound type have a destructor?
     pub fn has_destructor(&self, ctx: &BindgenContext) -> bool {
         if self.detect_has_destructor_cycle.get() {
@@ -373,19 +891,18 @@ impl CompInfo {
 
         let has_destructor = self.has_destructor ||
                              match self.kind {
             CompKind::Union => false,
             CompKind::Struct => {
                 self.base_members.iter().any(|base| {
                     ctx.resolve_type(base.ty).has_destructor(ctx)
                 }) ||
-                self.fields.iter().any(|field| {
-                    ctx.resolve_type(field.ty)
-                        .has_destructor(ctx)
+                self.fields().iter().any(|field| {
+                    field.has_destructor(ctx)
                 })
             }
         };
 
         self.detect_has_destructor_cycle.set(false);
 
         has_destructor
     }
@@ -395,39 +912,44 @@ impl CompInfo {
     /// This is called as a fallback under some circumstances where LLVM doesn't
     /// give us the correct layout.
     ///
     /// If we're a union without known layout, we try to compute it from our
     /// members. This is not ideal, but clang fails to report the size for these
     /// kind of unions, see test/headers/template_union.hpp
     pub fn layout(&self, ctx: &BindgenContext) -> Option<Layout> {
         use std::cmp;
+
         // We can't do better than clang here, sorry.
         if self.kind == CompKind::Struct {
             return None;
         }
 
         let mut max_size = 0;
         let mut max_align = 0;
-        for field in &self.fields {
-            let field_layout = ctx.resolve_type(field.ty)
-                .layout(ctx);
+        for field in self.fields() {
+            let field_layout = field.layout(ctx);
 
             if let Some(layout) = field_layout {
                 max_size = cmp::max(max_size, layout.size);
                 max_align = cmp::max(max_align, layout.align);
             }
         }
 
         Some(Layout::new(max_size, max_align))
     }
 
     /// Get this type's set of fields.
     pub fn fields(&self) -> &[Field] {
-        &self.fields
+        match self.fields {
+            CompFields::AfterComputingBitfieldUnits(ref fields) => fields,
+            CompFields::BeforeComputingBitfieldUnits(_) => {
+                panic!("Should always have computed bitfield units first");
+            }
+        }
     }
 
     /// Does this type have any template parameters that aren't types
     /// (e.g. int)?
     pub fn has_non_type_template_params(&self) -> bool {
         self.has_non_type_template_params
     }
 
@@ -455,16 +977,21 @@ impl CompInfo {
         self.destructor
     }
 
     /// What kind of compound type is this?
     pub fn kind(&self) -> CompKind {
         self.kind
     }
 
+    /// Is this a union?
+    pub fn is_union(&self) -> bool {
+        self.kind() == CompKind::Union
+    }
+
     /// The set of types that this one inherits from.
     pub fn base_members(&self) -> &[Base] {
         &self.base_members
     }
 
     /// Construct a new compound type from a Clang type.
     pub fn from_ty(potential_id: ItemId,
                    ty: &clang::Type,
@@ -505,42 +1032,42 @@ impl CompInfo {
                     if cur.kind() == CXCursor_TypedefDecl &&
                        cur.typedef_type().unwrap().canonical_type() == clang_ty {
                         // Typedefs of anonymous structs appear later in the ast
                         // than the struct itself, that would otherwise be an
                         // anonymous field. Detect that case here, and do
                         // nothing.
                     } else {
                         let field =
-                            Field::new(None, ty, None, None, None, false, offset);
-                        ci.fields.push(field);
+                            RawField::new(None, ty, None, None, None, false, offset);
+                        ci.fields.append_raw_field(field);
                     }
                 }
             }
 
             match cur.kind() {
                 CXCursor_FieldDecl => {
                     if let Some((ty, clang_ty, offset)) =
                         maybe_anonymous_struct_field.take() {
                         let mut used = false;
                         cur.visit(|child| {
                             if child.cur_type() == clang_ty {
                                 used = true;
                             }
                             CXChildVisit_Continue
                         });
                         if !used {
-                            let field = Field::new(None,
+                            let field = RawField::new(None,
                                                    ty,
                                                    None,
                                                    None,
                                                    None,
                                                    false,
                                                    offset);
-                            ci.fields.push(field);
+                            ci.fields.append_raw_field(field);
                         }
                     }
 
                     let bit_width = cur.bit_width();
                     let field_type = Item::from_ty_or_ref(cur.cur_type(),
                                                           cur,
                                                           Some(potential_id),
                                                           ctx);
@@ -553,24 +1080,24 @@ impl CompInfo {
 
                     // Name can be empty if there are bitfields, for example,
                     // see tests/headers/struct_with_bitfields.h
                     assert!(!name.is_empty() || bit_width.is_some(),
                             "Empty field name?");
 
                     let name = if name.is_empty() { None } else { Some(name) };
 
-                    let field = Field::new(name,
+                    let field = RawField::new(name,
                                            field_type,
                                            comment,
                                            annotations,
                                            bit_width,
                                            is_mutable,
                                            offset);
-                    ci.fields.push(field);
+                    ci.fields.append_raw_field(field);
 
                     // No we look for things like attributes and stuff.
                     cur.visit(|cur| {
                         if cur.kind() == CXCursor_UnexposedAttr {
                             ci.found_unknown_attr = true;
                         }
                         CXChildVisit_Continue
                     });
@@ -739,18 +1266,18 @@ impl CompInfo {
                           cur.location());
                 }
             }
             CXChildVisit_Continue
         });
 
         if let Some((ty, _, offset)) = maybe_anonymous_struct_field {
             let field =
-                Field::new(None, ty, None, None, None, false, offset);
-            ci.fields.push(field);
+                RawField::new(None, ty, None, None, None, false, offset);
+            ci.fields.append_raw_field(field);
         }
 
         Ok(ci)
     }
 
     fn kind_from_cursor(cursor: &clang::Cursor)
                         -> Result<CompKind, ParseError> {
         use clang_sys::*;
@@ -812,16 +1339,63 @@ impl CompInfo {
                 .map_or(false, |ci| ci.has_vtable(ctx))
         })
     }
 
     /// Returns true if compound type has been forward declared
     pub fn is_forward_declaration(&self) -> bool {
         self.is_forward_declaration
     }
+
+    /// Compute this compound structure's bitfield allocation units.
+    pub fn compute_bitfield_units(&mut self, ctx: &BindgenContext) {
+        self.fields.compute_bitfield_units(ctx);
+    }
+}
+
+impl DotAttributes for CompInfo {
+    fn dot_attributes<W>(&self, ctx: &BindgenContext, out: &mut W) -> io::Result<()>
+        where W: io::Write
+    {
+        writeln!(out, "<tr><td>CompKind</td><td>{:?}</td></tr>", self.kind)?;
+
+        if self.has_vtable {
+            writeln!(out, "<tr><td>has_vtable</td><td>true</td></tr>")?;
+        }
+
+        if self.has_destructor {
+            writeln!(out, "<tr><td>has_destructor</td><td>true</td></tr>")?;
+        }
+
+        if self.has_nonempty_base {
+            writeln!(out, "<tr><td>has_nonempty_base</td><td>true</td></tr>")?;
+        }
+
+        if self.has_non_type_template_params {
+            writeln!(out, "<tr><td>has_non_type_template_params</td><td>true</td></tr>")?;
+        }
+
+        if self.packed {
+            writeln!(out, "<tr><td>packed</td><td>true</td></tr>")?;
+        }
+
+        if self.is_forward_declaration {
+            writeln!(out, "<tr><td>is_forward_declaration</td><td>true</td></tr>")?;
+        }
+
+        if !self.fields().is_empty() {
+            writeln!(out, r#"<tr><td>fields</td><td><table border="0">"#)?;
+            for field in self.fields() {
+                field.dot_attributes(ctx, out)?;
+            }
+            writeln!(out, "</table></td></tr>")?;
+        }
+
+        Ok(())
+    }
 }
 
 impl TemplateParameters for CompInfo {
     fn self_template_params(&self,
                             _ctx: &BindgenContext)
                             -> Option<Vec<ItemId>> {
         if self.template_params.is_empty() {
             None
@@ -860,17 +1434,17 @@ impl CanDeriveDebug for CompInfo {
         }
 
         self.detect_derive_debug_cycle.set(true);
 
         let can_derive_debug = {
             self.base_members
                 .iter()
                 .all(|base| base.ty.can_derive_debug(ctx, ())) &&
-            self.fields
+            self.fields()
                 .iter()
                 .all(|f| f.can_derive_debug(ctx, ()))
         };
 
         self.detect_derive_debug_cycle.set(false);
 
         can_derive_debug
     }
@@ -902,17 +1476,17 @@ impl CanDeriveDefault for CompInfo {
 
         self.detect_derive_default_cycle.set(true);
 
         let can_derive_default = !self.has_vtable(ctx) &&
                                  !self.needs_explicit_vtable(ctx) &&
                                  self.base_members
             .iter()
             .all(|base| base.ty.can_derive_default(ctx, ())) &&
-                                 self.fields
+                                 self.fields()
             .iter()
             .all(|f| f.can_derive_default(ctx, ()));
 
         self.detect_derive_default_cycle.set(false);
 
         can_derive_default
     }
 }
@@ -948,17 +1522,17 @@ impl<'a> CanDeriveCopy<'a> for CompInfo 
                item.used_template_params(ctx).is_some() {
                 return false;
             }
         }
 
         self.base_members
             .iter()
             .all(|base| base.ty.can_derive_copy(ctx, ())) &&
-        self.fields.iter().all(|field| field.can_derive_copy(ctx, ()))
+        self.fields().iter().all(|field| field.can_derive_copy(ctx, ()))
     }
 
     fn can_derive_copy_in_array(&self,
                                 ctx: &BindgenContext,
                                 extra: (&Item, Option<Layout>))
                                 -> bool {
         self.can_derive_copy(ctx, extra)
     }
@@ -985,19 +1559,17 @@ impl Trace for CompInfo {
         if item.is_opaque(context) {
             return;
         }
 
         for base in self.base_members() {
             tracer.visit_kind(base.ty, EdgeKind::BaseMember);
         }
 
-        for field in self.fields() {
-            tracer.visit_kind(field.ty(), EdgeKind::Field);
-        }
+        self.fields.trace(context, tracer, &());
 
         for &var in self.inner_vars() {
             tracer.visit_kind(var, EdgeKind::InnerVar);
         }
 
         for method in self.methods() {
             tracer.visit_kind(method.signature, EdgeKind::Method);
         }
--- a/third_party/rust/bindgen/src/ir/context.rs
+++ b/third_party/rust/bindgen/src/ir/context.rs
@@ -16,16 +16,17 @@ use clang::{self, Cursor};
 use clang_sys;
 use parse::ClangItemParser;
 use std::borrow::Cow;
 use std::cell::Cell;
 use std::collections::{HashMap, hash_map};
 use std::collections::btree_map::{self, BTreeMap};
 use std::fmt;
 use std::iter::IntoIterator;
+use std::mem;
 use syntax::ast::Ident;
 use syntax::codemap::{DUMMY_SP, Span};
 use syntax::ext::base::ExtCtxt;
 
 /// A single identifier for an item.
 ///
 /// TODO: Build stronger abstractions on top of this, like TypeId(ItemId)?
 #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
@@ -155,16 +156,20 @@ pub struct BindgenContext<'ctx> {
 
     /// Whether a bindgen complex was generated
     generated_bindegen_complex: Cell<bool>,
 
     /// Map from an item's id to the set of template parameter items that it
     /// uses. See `ir::named` for more details. Always `Some` during the codegen
     /// phase.
     used_template_parameters: Option<HashMap<ItemId, ItemSet>>,
+
+    /// The set of `TypeKind::Comp` items found during parsing that need their
+    /// bitfield allocation units computed. Drained in `compute_bitfield_units`.
+    need_bitfield_allocation: Vec<ItemId>,
 }
 
 /// A traversal of whitelisted items.
 pub struct WhitelistedItems<'ctx, 'gen>
     where 'gen: 'ctx
 {
     ctx: &'ctx BindgenContext<'gen>,
     traversal: ItemTraversal<'ctx,
@@ -242,16 +247,17 @@ impl<'ctx> BindgenContext<'ctx> {
             collected_typerefs: false,
             gen_ctx: None,
             span: DUMMY_SP,
             index: index,
             translation_unit: translation_unit,
             options: options,
             generated_bindegen_complex: Cell::new(false),
             used_template_parameters: None,
+            need_bitfield_allocation: Default::default(),
         };
 
         me.add_item(root_module, None, None);
 
         me
     }
 
     /// Get the stack of partially parsed types that we are in the middle of
@@ -294,35 +300,41 @@ impl<'ctx> BindgenContext<'ctx> {
         debug_assert!(declaration.is_some() || !item.kind().is_type() ||
                       item.kind().expect_type().is_builtin_or_named() ||
                       item.kind().expect_type().is_opaque(),
                       "Adding a type without declaration?");
 
         let id = item.id();
         let is_type = item.kind().is_type();
         let is_unnamed = is_type && item.expect_type().name().is_none();
+        let is_template_instantiation =
+            is_type && item.expect_type().is_template_instantiation();
 
         // Be sure to track all the generated children under namespace, even
         // those generated after resolving typerefs, etc.
         if item.id() != item.parent_id() {
             if let Some(mut parent) = self.items.get_mut(&item.parent_id()) {
                 if let Some(mut module) = parent.as_module_mut() {
                     module.children_mut().push(item.id());
                 }
             }
         }
 
+        if is_type && item.expect_type().is_comp() {
+            self.need_bitfield_allocation.push(id);
+        }
+
         let old_item = self.items.insert(id, item);
         assert!(old_item.is_none(),
                 "should not have already associated an item with the given id");
 
         // Unnamed items can have an USR, but they can't be referenced from
         // other sites explicitly and the USR can match if the unnamed items are
         // nested, so don't bother tracking them.
-        if is_type && declaration.is_some() {
+        if is_type && !is_template_instantiation && declaration.is_some() {
             let mut declaration = declaration.unwrap();
             if !declaration.is_valid() {
                 if let Some(location) = location {
                     if location.is_template_like() {
                         declaration = location;
                     }
                 }
             }
@@ -479,16 +491,42 @@ impl<'ctx> BindgenContext<'ctx> {
 
             // Something in the STL is trolling me. I don't need this assertion
             // right now, but worth investigating properly once this lands.
             //
             // debug_assert!(self.items.get(&resolved).is_some(), "How?");
         }
     }
 
+    /// Compute the bitfield allocation units for all `TypeKind::Comp` items we
+    /// parsed.
+    fn compute_bitfield_units(&mut self) {
+        assert!(self.collected_typerefs());
+
+        let need_bitfield_allocation = mem::replace(&mut self.need_bitfield_allocation, vec![]);
+        for id in need_bitfield_allocation {
+            // To appease the borrow checker, we temporarily remove this item
+            // from the context, and then replace it once we are done computing
+            // its bitfield units. We will never try and resolve this
+            // `TypeKind::Comp` item's id (which would now cause a panic) during
+            // bitfield unit computation because it is a non-scalar by
+            // definition, and non-scalar types may not be used as bitfields.
+            let mut item = self.items.remove(&id).unwrap();
+
+            item.kind_mut()
+                .as_type_mut()
+                .unwrap()
+                .as_comp_mut()
+                .unwrap()
+                .compute_bitfield_units(&*self);
+
+            self.items.insert(id, item);
+        }
+    }
+
     /// Iterate over all items and replace any item that has been named in a
     /// `replaces="SomeType"` annotation with the replacement type.
     fn process_replacements(&mut self) {
         if self.replacements.is_empty() {
             debug!("No replacements to process");
             return;
         }
 
@@ -610,16 +648,17 @@ impl<'ctx> BindgenContext<'ctx> {
         // of BindgenContext instead, I guess. Even though we know it's fine
         // because we remove it before the end of this function.
         self.gen_ctx = Some(unsafe { mem::transmute(&ctx) });
 
         self.assert_no_dangling_references();
 
         if !self.collected_typerefs() {
             self.resolve_typerefs();
+            self.compute_bitfield_units();
             self.process_replacements();
         }
 
         self.find_used_template_parameters();
 
         let ret = cb(self);
         self.gen_ctx = None;
         ret
--- a/third_party/rust/bindgen/src/ir/dot.rs
+++ b/third_party/rust/bindgen/src/ir/dot.rs
@@ -25,17 +25,17 @@ pub fn write_dot_file<P>(ctx: &BindgenCo
     let file = try!(File::create(path));
     let mut dot_file = io::BufWriter::new(file);
     try!(writeln!(&mut dot_file, "digraph {{"));
 
     let mut err: Option<io::Result<_>> = None;
 
     for (id, item) in ctx.items() {
         try!(writeln!(&mut dot_file,
-                      r#"{} [fontname="courier", label=< <table border="0">"#,
+                      r#"{} [fontname="courier", label=< <table border="0" align="left">"#,
                       id.as_usize()));
         try!(item.dot_attributes(ctx, &mut dot_file));
         try!(writeln!(&mut dot_file, r#"</table> >];"#));
 
         item.trace(ctx,
                    &mut |sub_id: ItemId, edge_kind| {
             if err.is_some() {
                 return;
--- a/third_party/rust/bindgen/src/ir/item.rs
+++ b/third_party/rust/bindgen/src/ir/item.rs
@@ -365,26 +365,26 @@ impl<'a> CanDeriveCopy<'a> for Item {
 /// Note that even though we parse all the types of annotations in comments, not
 /// all of them apply to every item. Those rules are described in the
 /// `annotations` module.
 #[derive(Debug)]
 pub struct Item {
     /// This item's id.
     id: ItemId,
 
-    /// The item's local id, unique only amongst its siblings.  Only used for
+    /// The item's local id, unique only amongst its siblings. Only used for
     /// anonymous items.
     ///
     /// Lazily initialized in local_id().
     ///
     /// Note that only structs, unions, and enums get a local type id. In any
     /// case this is an implementation detail.
     local_id: Cell<Option<usize>>,
 
-    /// The next local id to use for a child..
+    /// The next local id to use for a child or template instantiation.
     next_child_local_id: Cell<usize>,
 
     /// A cached copy of the canonical name, as returned by `canonical_name`.
     ///
     /// This is a fairly used operation during codegen so this makes bindgen
     /// considerably faster in those cases.
     canonical_name_cache: RefCell<Option<String>>,
 
@@ -485,23 +485,33 @@ impl Item {
     /// Get an identifier that differentiates this item from its siblings.
     ///
     /// This should stay relatively stable in the face of code motion outside or
     /// below this item's lexical scope, meaning that this can be useful for
     /// generating relatively stable identifiers within a scope.
     pub fn local_id(&self, ctx: &BindgenContext) -> usize {
         if self.local_id.get().is_none() {
             let parent = ctx.resolve_item(self.parent_id);
-            let local_id = parent.next_child_local_id.get();
-            parent.next_child_local_id.set(local_id + 1);
-            self.local_id.set(Some(local_id));
+            self.local_id.set(Some(parent.next_child_local_id()));
         }
         self.local_id.get().unwrap()
     }
 
+    /// Get an identifier that differentiates a child of this item of other
+    /// related items.
+    ///
+    /// This is currently used for anonymous items, and template instantiation
+    /// tests, in both cases in order to reduce noise when system headers are at
+    /// place.
+    pub fn next_child_local_id(&self) -> usize {
+        let local_id = self.next_child_local_id.get();
+        self.next_child_local_id.set(local_id + 1);
+        local_id
+    }
+
     /// Returns whether this item is a top-level item, from the point of view of
     /// bindgen.
     ///
     /// This point of view changes depending on whether namespaces are enabled
     /// or not. That way, in the following example:
     ///
     /// ```c++
     /// namespace foo {
@@ -772,23 +782,26 @@ impl Item {
             names.push(base_name);
         }
 
         let name = names.join("_");
 
         ctx.rust_mangle(&name).into_owned()
     }
 
-    fn exposed_id(&self, ctx: &BindgenContext) -> String {
+    /// The exposed id that represents an unique id among the siblings of a
+    /// given item.
+    pub fn exposed_id(&self, ctx: &BindgenContext) -> String {
         // Only use local ids for enums, classes, structs and union types.  All
         // other items use their global id.
         let ty_kind = self.kind().as_type().map(|t| t.kind());
         if let Some(ty_kind) = ty_kind {
             match *ty_kind {
                 TypeKind::Comp(..) |
+                TypeKind::TemplateInstantiation(..) |
                 TypeKind::Enum(..) => return self.local_id(ctx).to_string(),
                 _ => {}
             }
         }
 
         // Note that this `id_` prefix prevents (really unlikely) collisions
         // between the global id and the local id of an item with the same
         // parent.
@@ -824,16 +837,21 @@ impl DotAttributes for Item {
                          -> io::Result<()>
         where W: io::Write,
     {
         try!(writeln!(out,
                       "<tr><td>{:?}</td></tr>
                        <tr><td>name</td><td>{}</td></tr>",
                       self.id,
                       self.name(ctx).get()));
+
+        if self.is_opaque(ctx) {
+            writeln!(out, "<tr><td>opaque</td><td>true</td></tr>")?;
+        }
+
         self.kind.dot_attributes(ctx, out)
     }
 }
 
 impl TemplateParameters for ItemId {
     fn self_template_params(&self,
                             ctx: &BindgenContext)
                             -> Option<Vec<ItemId>> {
--- a/third_party/rust/bindgen/src/ir/template.rs
+++ b/third_party/rust/bindgen/src/ir/template.rs
@@ -228,42 +228,58 @@ impl TemplateInstantiation {
     /// Parse a `TemplateInstantiation` from a clang `Type`.
     pub fn from_ty(ty: &clang::Type,
                    ctx: &mut BindgenContext)
                    -> Option<TemplateInstantiation> {
         use clang_sys::*;
 
         let template_args = ty.template_args()
             .map_or(vec![], |args| {
-                args.filter(|t| t.kind() != CXType_Invalid)
-                    .map(|t| {
-                        Item::from_ty_or_ref(t, t.declaration(), None, ctx)
-                    })
-                    .collect()
+                match ty.canonical_type().template_args() {
+                    Some(canonical_args) => {
+                        let arg_count = args.len();
+                        args.chain(canonical_args.skip(arg_count))
+                            .filter(|t| t.kind() != CXType_Invalid)
+                            .map(|t| {
+                                Item::from_ty_or_ref(t, t.declaration(), None, ctx)
+                            }).collect()
+                    }
+                    None => {
+                        args.filter(|t| t.kind() != CXType_Invalid)
+                            .map(|t| {
+                                Item::from_ty_or_ref(t, t.declaration(), None, ctx)
+                            }).collect()
+                    }
+                }
             });
 
-        let definition = ty.declaration()
-            .specialized()
-            .or_else(|| {
-                let mut template_ref = None;
-                ty.declaration().visit(|child| {
-                    if child.kind() == CXCursor_TemplateRef {
-                        template_ref = Some(child);
-                        return CXVisit_Break;
-                    }
+        let declaration = ty.declaration();
+        let definition = if declaration.kind() == CXCursor_TypeAliasTemplateDecl {
+            Some(declaration)
+        } else {
+            declaration
+                .specialized()
+                .or_else(|| {
+                    let mut template_ref = None;
+                    ty.declaration().visit(|child| {
+                        if child.kind() == CXCursor_TemplateRef {
+                            template_ref = Some(child);
+                            return CXVisit_Break;
+                        }
 
-                    // Instantiations of template aliases might have the
-                    // TemplateRef to the template alias definition arbitrarily
-                    // deep, so we need to recurse here and not only visit
-                    // direct children.
-                    CXChildVisit_Recurse
-                });
+                        // Instantiations of template aliases might have the
+                        // TemplateRef to the template alias definition arbitrarily
+                        // deep, so we need to recurse here and not only visit
+                        // direct children.
+                        CXChildVisit_Recurse
+                    });
 
-                template_ref.and_then(|cur| cur.referenced())
-            });
+                    template_ref.and_then(|cur| cur.referenced())
+                })
+        };
 
         let definition = match definition {
             Some(def) => def,
             None => {
                 if !ty.declaration().is_builtin() {
                     warn!("Could not find template definition for template \
                            instantiation");
                 }
--- a/third_party/rust/bindgen/src/ir/ty.rs
+++ b/third_party/rust/bindgen/src/ir/ty.rs
@@ -50,16 +50,25 @@ impl Type {
     /// other kind of type.
     pub fn as_comp(&self) -> Option<&CompInfo> {
         match self.kind {
             TypeKind::Comp(ref ci) => Some(ci),
             _ => None,
         }
     }
 
+    /// Get the underlying `CompInfo` for this type as a mutable reference, or
+    /// `None` if this is some other kind of type.
+    pub fn as_comp_mut(&mut self) -> Option<&mut CompInfo> {
+        match self.kind {
+            TypeKind::Comp(ref mut ci) => Some(ci),
+            _ => None,
+        }
+    }
+
     /// Construct a new `Type`.
     pub fn new(name: Option<String>,
                layout: Option<Layout>,
                kind: TypeKind,
                is_const: bool)
                -> Self {
         Type {
             name: name,
@@ -104,16 +113,24 @@ impl Type {
     /// Is this type of kind `TypeKind::Named`?
     pub fn is_named(&self) -> bool {
         match self.kind {
             TypeKind::Named => true,
             _ => false,
         }
     }
 
+    /// Is this a template instantiation type?
+    pub fn is_template_instantiation(&self) -> bool {
+        match self.kind {
+            TypeKind::TemplateInstantiation(..) => true,
+            _ => false,
+        }
+    }
+
     /// Is this a template alias type?
     pub fn is_template_alias(&self) -> bool {
         match self.kind {
             TypeKind::TemplateAlias(..) => true,
             _ => false,
         }
     }
 
@@ -400,17 +417,17 @@ impl DotAttributes for Type {
         }
 
         self.kind.dot_attributes(ctx, out)
     }
 }
 
 impl DotAttributes for TypeKind {
     fn dot_attributes<W>(&self,
-                         _ctx: &BindgenContext,
+                         ctx: &BindgenContext,
                          out: &mut W)
                          -> io::Result<()>
         where W: io::Write,
     {
         write!(out,
                "<tr><td>TypeKind</td><td>{}</td></tr>",
                match *self {
                    TypeKind::Void => "Void",
@@ -430,17 +447,22 @@ impl DotAttributes for TypeKind {
                    TypeKind::Reference(..) => "Reference",
                    TypeKind::TemplateInstantiation(..) => "TemplateInstantiation",
                    TypeKind::ResolvedTypeRef(..) => "ResolvedTypeRef",
                    TypeKind::Named => "Named",
                    TypeKind::ObjCId => "ObjCId",
                    TypeKind::ObjCSel => "ObjCSel",
                    TypeKind::ObjCInterface(..) => "ObjCInterface",
                    TypeKind::UnresolvedTypeRef(..) => unreachable!("there shouldn't be any more of these anymore"),
-               })
+               })?;
+        if let TypeKind::Comp(ref comp) = *self {
+            comp.dot_attributes(ctx, out)?;
+        }
+
+        Ok(())
     }
 }
 
 #[test]
 fn is_invalid_named_type_valid() {
     let ty = Type::new(Some("foo".into()), None, TypeKind::Named, false);
     assert!(!ty.is_invalid_named_type())
 }
--- a/third_party/rust/bindgen/src/lib.rs
+++ b/third_party/rust/bindgen/src/lib.rs
@@ -20,16 +20,17 @@
 #[macro_use]
 #[allow(unused_extern_crates)]
 extern crate cfg_if;
 extern crate cexpr;
 extern crate syntex_syntax as syntax;
 extern crate aster;
 extern crate quasi;
 extern crate clang_sys;
+extern crate peeking_take_while;
 extern crate regex;
 #[macro_use]
 extern crate lazy_static;
 
 #[cfg(feature = "logging")]
 #[macro_use]
 extern crate log;
 
--- a/third_party/rust/clang-sys/.cargo-checksum.json
+++ b/third_party/rust/clang-sys/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"09cd366a44271073e57584376fd326da166664cd8ff303c2839b63a330557c73",".travis.yml":"79d6a139814ae0f06ce0ca85fe22a27316a27d444320b904c471c7f612129889","CHANGELOG.md":"786e019493746e2a1a98fdd069e28103acf146c0093814b74b54f145665c6428","CONTRIBUTING.md":"4e2a45992604f07a37030bb1fc598c6f54a1785747c4f37a15a37481bbdecce8","Cargo.toml":"3c22785a6974cd8a051a0cb87090c480af3cab261df125ab7d408a77644b9cef","LICENSE.txt":"cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30","README.md":"92dc2a93f6de04e38d305df2d0ee4854269acbacadc665e6ce17b90f90ad29ca","appveyor.yml":"fe7033ab25bb78005136748676f59bfdd8f65b4c5c2910af911cbb9c496bdaef","build.rs":"1c5172ffc51fdf00f35b8366945ab98d644d386bcb12eb773990253adb000c80","ci/before_install.sh":"402f5704cd0163254b056a515a6cdfa16482eb2e28c31eb63a5c226abd26a8b7","ci/install.bat":"d694550679e14b384f8adf8384d475866e5880002cf82d450926f4607dc9077b","ci/script.sh":"1bb1cd29bd9635cc126cdcbd6c02f3500620a231a86726bf2165a4b74baaf433","ci/test_script.bat":"73462f51aaa9a1c14ce9f55c41dc3672df64faa9789725384ae4f28d8ba3c90b","clippy.toml":"acef14b9acffa18d1069ae08a4e8fe824a614f91b0bc71a6b1c68e4d885397e6","src/lib.rs":"f27371163edaec30a3972667318320b060adff25c03a850a9e807f84c9bc395f","src/link.rs":"b9f76e26fa9b1d690f6abf17e9f898d6545be149e2afe64c7411cd53e3168fcf","src/support.rs":"1e48fcb7dc9e7f4dde06d88079074832a4c2dab337228e05241b7d7e94858734","tests/header.h":"b1cf564b21d76db78529d1934e1481a5f0452fdedc6e32954608293c310498b6","tests/lib.rs":"9225ffcaa892a3901c0dce9f8190421db8fb17651499b4de765b87f08daaf5b2"},"package":"33d47b0ea88a529a570490efbb79403e416e89864ce8a96bf23e2a0f23d7e9eb"}
\ No newline at end of file
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"09cd366a44271073e57584376fd326da166664cd8ff303c2839b63a330557c73",".travis.yml":"79d6a139814ae0f06ce0ca85fe22a27316a27d444320b904c471c7f612129889","CHANGELOG.md":"bd7194bb4c1572c3c34764853a871649bb4f8a20bd7fe6ef96aa8c49d3eb79a9","CONTRIBUTING.md":"4e2a45992604f07a37030bb1fc598c6f54a1785747c4f37a15a37481bbdecce8","Cargo.toml":"88bc28832d77f741028cb5ca9d387a7f016275256cf8f8542b94f2bcc5e8983b","LICENSE.txt":"cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30","README.md":"73c5156eeff880c0c0ea80a2eb2926797fd06376118e23f842b4164ad677d4f1","appveyor.yml":"fe7033ab25bb78005136748676f59bfdd8f65b4c5c2910af911cbb9c496bdaef","build.rs":"2b934b1cd30083531d4b751f8fe22f997e07ffc35631f15a734574d1d2fa0900","ci/before_install.sh":"402f5704cd0163254b056a515a6cdfa16482eb2e28c31eb63a5c226abd26a8b7","ci/install.bat":"d694550679e14b384f8adf8384d475866e5880002cf82d450926f4607dc9077b","ci/script.sh":"1bb1cd29bd9635cc126cdcbd6c02f3500620a231a86726bf2165a4b74baaf433","ci/test_script.bat":"73462f51aaa9a1c14ce9f55c41dc3672df64faa9789725384ae4f28d8ba3c90b","clippy.toml":"acef14b9acffa18d1069ae08a4e8fe824a614f91b0bc71a6b1c68e4d885397e6","src/lib.rs":"f27371163edaec30a3972667318320b060adff25c03a850a9e807f84c9bc395f","src/link.rs":"b9f76e26fa9b1d690f6abf17e9f898d6545be149e2afe64c7411cd53e3168fcf","src/support.rs":"1e48fcb7dc9e7f4dde06d88079074832a4c2dab337228e05241b7d7e94858734","tests/header.h":"b1cf564b21d76db78529d1934e1481a5f0452fdedc6e32954608293c310498b6","tests/lib.rs":"9225ffcaa892a3901c0dce9f8190421db8fb17651499b4de765b87f08daaf5b2"},"package":"ff7c2d1502c65748c7221f43ce670b3ba5c697acebfeb85a580827daca6975fc"}
\ No newline at end of file
--- a/third_party/rust/clang-sys/CHANGELOG.md
+++ b/third_party/rust/clang-sys/CHANGELOG.md
@@ -1,12 +1,17 @@
+## [0.18.0] - 2017-05-16
+
+### Changed
+- Improved finding of versioned libraries (e.g., `libclang.so.3.9`)
+
 ## [0.17.0] - 2017-05-08
 
 ### Changed
-- Change storage type of include search paths from `Vec<PathBuf>` to `Option<Vec<PathBuf>>`
+- Changed storage type of include search paths from `Vec<PathBuf>` to `Option<Vec<PathBuf>>`
 
 ## [0.16.0] - 2017-05-02
 
 ### Changed
 - Bumped `libloading` version to `0.4.0`
 
 ## [0.15.2] - 2017-04-28
 
--- a/third_party/rust/clang-sys/Cargo.toml
+++ b/third_party/rust/clang-sys/Cargo.toml
@@ -1,14 +1,14 @@
 [package]
 
 name = "clang-sys"
 authors = ["Kyle Mayes <kyle@mayeses.com>"]
 
-version = "0.17.0"
+version = "0.18.0"
 
 readme = "README.md"
 license = "Apache-2.0"
 
 description = "Rust bindings for libclang."
 
 documentation = "https://kylemayes.github.io/clang-sys/3_5/clang_sys"
 repository = "https://github.com/KyleMayes/clang-sys"
--- a/third_party/rust/clang-sys/README.md
+++ b/third_party/rust/clang-sys/README.md
@@ -42,19 +42,26 @@ depends on the `libclang` shared library
 `libclang.dll` on Windows). If you want to link to `libclang` statically instead, enable the
 `static` Cargo feature. In this case, this crate depends on the LLVM and Clang static libraries. If
 you don't want to link to `libclang` at compiletime but instead want to load it at runtime, enable
 the `runtime` Cargo feature.
 
 These libraries can be either be installed as a part of Clang or downloaded
 [here](http://llvm.org/releases/download.html).
 
-**Note:** Installing `libclang` through a package manager might install the `libclang` shared
-library as something like `libclang.so.1` instead of `libclang.so`. In this case, you need to make a
-symbolic link from the versioned shared library to `libclang.so`.
+**Note:** This crate supports finding versioned instances of `libclang.so` (e.g.,
+`libclang.so.3.9`). In the case where there are multiple instances to choose from, this crate will
+prefer an unversioned instance first, then the version with the shortest and highest version. For
+example, the following instances of `libclang.so` are listed in descending order of preference:
+
+1. `libclang.so`
+2. `libclang.so.4`
+3. `libclang.so.4.0`
+4. `libclang.so.3`
+5. `libclang.so.3.9`
 
 **Note:** The downloads for LLVM and Clang 3.8 and later do not include the `libclang.a` static
 library. This means you cannot link to any of these versions of `libclang` statically unless you
 build it from source.
 
 ## Environment Variables
 
 The following environment variables, if set, are used by this crate to find the required libraries
--- a/third_party/rust/clang-sys/build.rs
+++ b/third_party/rust/clang-sys/build.rs
@@ -34,19 +34,44 @@ extern crate glob;
 use std::env;
 use std::fs::{self, File};
 use std::io::{Read};
 use std::path::{Path, PathBuf};
 use std::process::{Command};
 
 use glob::{MatchOptions};
 
+/// Returns the components of the version appended to the supplied file.
+fn parse_version(file: &Path) -> Vec<u32> {
+    let string = file.to_str().unwrap_or("");
+    let components = string.split('.').skip(2);
+    components.map(|s| s.parse::<u32>().unwrap_or(0)).collect()
+}
+
 /// Returns a path to one of the supplied files if such a file can be found in the supplied directory.
-fn contains<D: AsRef<Path>>(directory: D, files: &[String]) -> Option<PathBuf> {
-    files.iter().map(|file| directory.as_ref().join(file)).find(|file| file.exists())
+fn contains(directory: &Path, files: &[String]) -> Option<PathBuf> {
+    // Join the directory to the files to obtain our glob patterns.
+    let patterns = files.iter().filter_map(|f| directory.join(f).to_str().map(ToOwned::to_owned));
+
+    // Prevent wildcards from matching path separators.
+    let mut options = MatchOptions::new();
+    options.require_literal_separator = true;
+
+    // Collect any files that match the glob patterns.
+    let mut matches = patterns.flat_map(|p| {
+        if let Ok(paths) = glob::glob_with(&p, &options) {
+            paths.filter_map(Result::ok).collect()
+        } else {
+            vec![]
+        }
+    }).collect::<Vec<_>>();
+
+    // Sort the matches by their version, preferring shorter and higher versions.
+    matches.sort_by_key(|m| parse_version(m));
+    matches.pop()
 }
 
 /// Runs a console command, returning the output if the command was successfully executed.
 fn run(command: &str, arguments: &[&str]) -> Option<String> {
     Command::new(command).args(arguments).output().map(|o| {
         String::from_utf8_lossy(&o.stdout).into_owned()
     }).ok()
 }
@@ -208,21 +233,20 @@ fn find(library: Library, files: &[Strin
     );
     Err(message)
 }
 
 /// Searches for a `libclang` shared library, returning the path to such a shared library if the
 /// search was successful.
 pub fn find_shared_library() -> Result<PathBuf, String> {
     let mut files = vec![format!("{}clang{}", env::consts::DLL_PREFIX, env::consts::DLL_SUFFIX)];
-    if cfg!(target_os="linux") {
-        // Some Linux distributions don't create a `libclang.so` symlink.
-        //
-        // FIXME: We should improve our detection and selection of versioned libraries.
-        files.push("libclang.so.1".into());
+    if cfg!(any(target_os="freebsd", target_os="linux", target_os="openbsd")) {
+        // Some BSDs and Linux distributions don't create a `libclang.so` symlink, so we need to
+        // look for any versioned files (e.g., `libclang.so.3.9`).
+        files.push("libclang.so.*".into());
     }
     if cfg!(target_os="windows") {
         // The official LLVM build uses `libclang.dll` on Windows instead of `clang.dll`. However,
         // unofficial builds such as MinGW use `clang.dll`.
         files.push("libclang.dll".into());
     }
     find(Library::Dynamic, &files, "LIBCLANG_PATH")
 }
new file mode 100644
--- /dev/null
+++ b/third_party/rust/peeking_take_while/.cargo-checksum.json
@@ -0,0 +1,1 @@
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"1405b421de32d7744dd83162e9d640982ece71c6ccbd7ce2dc7df3d0b2c2c47d",".travis.yml":"9871eecb27ad6d76270d75534bd54581fab2a4feae93d114ae65a287ffbad5fe","Cargo.toml":"caf1a07b54869ad1b35394c5b9262fe1e8f63b7ab85bf517ad6d59c1ad1d64bc","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7b63ecd5f1902af1b63729947373683c32745c16a10e8e6292e2e2dcd7e90ae0","README.md":"9f7659439d3e98a3aae69562648a651e49eeac7152f489deb77dd09c0c8010d0","src/lib.rs":"699149181f71aa88dc6585bd047fc29c6f5baba2b8bf5fbd1c5612966322b379"},"package":"19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"}
\ No newline at end of file
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/third_party/rust/peeking_take_while/.gitignore
@@ -0,0 +1,3 @@
+target/
+**/*.rs.bk
+Cargo.lock
new file mode 100644
--- /dev/null
+++ b/third_party/rust/peeking_take_while/.travis.yml
@@ -0,0 +1,18 @@
+sudo: false
+language: rust
+
+rust:
+  - stable
+  - beta
+  - nightly
+
+cache: cargo
+
+env:
+  matrix:
+    - PROFILE=""
+    - PROFILE="--release"
+
+script:
+  - cargo build $PROFILE --verbose
+  - cargo test $PROFILE --verbose
new file mode 100644
--- /dev/null
+++ b/third_party/rust/peeking_take_while/Cargo.toml
@@ -0,0 +1,14 @@
+[package]
+authors = ["Nick Fitzgerald <fitzgen@gmail.com>"]
+description = "Like `Iterator::take_while`, but calls the predicate on a peeked value. This allows you to use `Iterator::by_ref` and `Iterator::take_while` together, and still get the first value for which the `take_while` predicate returned false after dropping the `by_ref`."
+categories = ["rust-patterns"]
+keywords = ["iterator", "take_while", "peek", "by_ref"]
+license = "Apache-2.0/MIT"
+name = "peeking_take_while"
+readme = "./README.md"
+repository = "https://github.com/fitzgen/peeking_take_while"
+version = "0.1.2"
+
+[badges]
+[badges.travis-ci]
+repository = "fitzgen/peeking_take_while"
new file mode 100644
--- /dev/null
+++ b/third_party/rust/peeking_take_while/LICENSE-APACHE
@@ -0,0 +1,201 @@
+                              Apache License
+                        Version 2.0, January 2004
+                     http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+   "License" shall mean the terms and conditions for use, reproduction,
+   and distribution as defined by Sections 1 through 9 of this document.
+
+   "Licensor" shall mean the copyright owner or entity authorized by
+   the copyright owner that is granting the License.
+
+   "Legal Entity" shall mean the union of the acting entity and all
+   other entities that control, are controlled by, or are under common
+   control with that entity. For the purposes of this definition,
+   "control" means (i) the power, direct or indirect, to cause the
+   direction or management of such entity, whether by contract or
+   otherwise, or (ii) ownership of fifty percent (50%) or more of the
+   outstanding shares, or (iii) beneficial ownership of such entity.
+
+   "You" (or "Your") shall mean an individual or Legal Entity
+   exercising permissions granted by this License.
+
+   "Source" form shall mean the preferred form for making modifications,
+   including but not limited to software source code, documentation
+   source, and configuration files.
+
+   "Object" form shall mean any form resulting from mechanical
+   transformation or translation of a Source form, including but
+   not limited to compiled object code, generated documentation,
+   and conversions to other media types.
+
+   "Work" shall mean the work of authorship, whether in Source or
+   Object form, made available under the License, as indicated by a
+   copyright notice that is included in or attached to the work
+   (an example is provided in the Appendix below).
+
+   "Derivative Works" shall mean any work, whether in Source or Object
+   form, that is based on (or derived from) the Work and for which the
+   editorial revisions, annotations, elaborations, or other modifications
+   represent, as a whole, an original work of authorship. For the purposes
+   of this License, Derivative Works shall not include works that remain
+   separable from, or merely link (or bind by name) to the interfaces of,
+   the Work and Derivative Works thereof.
+
+   "Contribution" shall mean any work of authorship, including
+   the original version of the Work and any modifications or additions
+   to that Work or Derivative Works thereof, that is intentionally
+   submitted to Licensor for inclusion in the Work by the copyright owner
+   or by an individual or Legal Entity authorized to submit on behalf of
+   the copyright owner. For the purposes of this definition, "submitted"
+   means any form of electronic, verbal, or written communication sent
+   to the Licensor or its representatives, including but not limited to
+   communication on electronic mailing lists, source code control systems,
+   and issue tracking systems that are managed by, or on behalf of, the
+   Licensor for the purpose of discussing and improving the Work, but
+   excluding communication that is conspicuously marked or otherwise
+   designated in writing by the copyright owner as "Not a Contribution."
+
+   "Contributor" shall mean Licensor and any individual or Legal Entity
+   on behalf of whom a Contribution has been received by Licensor and
+   subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   copyright license to reproduce, prepare Derivative Works of,
+   publicly display, publicly perform, sublicense, and distribute the
+   Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   (except as stated in this section) patent license to make, have made,
+   use, offer to sell, sell, import, and otherwise transfer the Work,
+   where such license applies only to those patent claims licensable
+   by such Contributor that are necessarily infringed by their
+   Contribution(s) alone or by combination of their Contribution(s)
+   with the Work to which such Contribution(s) was submitted. If You
+   institute patent litigation against any entity (including a
+   cross-claim or counterclaim in a lawsuit) alleging that the Work
+   or a Contribution incorporated within the Work constitutes direct
+   or contributory patent infringement, then any patent licenses
+   granted to You under this License for that Work shall terminate
+   as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+   Work or Derivative Works thereof in any medium, with or without
+   modifications, and in Source or Object form, provided that You
+   meet the following conditions:
+
+   (a) You must give any other recipients of the Work or
+       Derivative Works a copy of this License; and
+
+   (b) You must cause any modified files to carry prominent notices
+       stating that You changed the files; and
+
+   (c) You must retain, in the Source form of any Derivative Works
+       that You distribute, all copyright, patent, trademark, and
+       attribution notices from the Source form of the Work,
+       excluding those notices that do not pertain to any part of
+       the Derivative Works; and
+
+   (d) If the Work includes a "NOTICE" text file as part of its
+       distribution, then any Derivative Works that You distribute must
+       include a readable copy of the attribution notices contained
+       within such NOTICE file, excluding those notices that do not
+       pertain to any part of the Derivative Works, in at least one
+       of the following places: within a NOTICE text file distributed
+       as part of the Derivative Works; within the Source form or
+       documentation, if provided along with the Derivative Works; or,
+       within a display generated by the Derivative Works, if and
+       wherever such third-party notices normally appear. The contents
+       of the NOTICE file are for informational purposes only and
+       do not modify the License. You may add Your own attribution
+       notices within Derivative Works that You distribute, alongside
+       or as an addendum to the NOTICE text from the Work, provided
+       that such additional attribution notices cannot be construed
+       as modifying the License.
+
+   You may add Your own copyright statement to Your modifications and
+   may provide additional or different license terms and conditions
+   for use, reproduction, or distribution of Your modifications, or
+   for any such Derivative Works as a whole, provided Your use,
+   reproduction, and distribution of the Work otherwise complies with
+   the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+   any Contribution intentionally submitted for inclusion in the Work
+   by You to the Licensor shall be under the terms and conditions of
+   this License, without any additional terms or conditions.
+   Notwithstanding the above, nothing herein shall supersede or modify
+   the terms of any separate license agreement you may have executed
+   with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+   names, trademarks, service marks, or product names of the Licensor,
+   except as required for reasonable and customary use in describing the
+   origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+   agreed to in writing, Licensor provides the Work (and each
+   Contributor provides its Contributions) on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+   implied, including, without limitation, any warranties or conditions
+   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+   PARTICULAR PURPOSE. You are solely responsible for determining the
+   appropriateness of using or redistributing the Work and assume any
+   risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+   whether in tort (including negligence), contract, or otherwise,
+   unless required by applicable law (such as deliberate and grossly
+   negligent acts) or agreed to in writing, shall any Contributor be
+   liable to You for damages, including any direct, indirect, special,
+   incidental, or consequential damages of any character arising as a
+   result of this License or out of the use or inability to use the
+   Work (including but not limited to damages for loss of goodwill,
+   work stoppage, computer failure or malfunction, or any and all
+   other commercial damages or losses), even if such Contributor
+   has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+   the Work or Derivative Works thereof, You may choose to offer,
+   and charge a fee for, acceptance of support, warranty, indemnity,
+   or other liability obligations and/or rights consistent with this
+   License. However, in accepting such obligations, You may act only
+   on Your own behalf and on Your sole responsibility, not on behalf
+   of any other Contributor, and only if You agree to indemnify,
+   defend, and hold each Contributor harmless for any liability
+   incurred by, or claims asserted against, such Contributor by reason
+   of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+   To apply the Apache License to your work, attach the following
+   boilerplate notice, with the fields enclosed by brackets "[]"
+   replaced with your own identifying information. (Don't include
+   the brackets!)  The text should be enclosed in the appropriate
+   comment syntax for the file format. We also recommend that a
+   file or class name and description of purpose be included on the
+   same "printed page" as the copyright notice for easier
+   identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+	http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/peeking_take_while/LICENSE-MIT
@@ -0,0 +1,25 @@
+Copyright (c) 2015 The Rust Project Developers
+
+Permission is hereby granted, free of charge, to any
+person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the
+Software without restriction, including without
+limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software
+is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/peeking_take_while/README.md
@@ -0,0 +1,58 @@
+# `peeking_take_while`
+
+[![Build Status](https://travis-ci.org/fitzgen/peeking_take_while.png?branch=master)](https://travis-ci.org/fitzgen/peeking_take_while)
+
+Provides the `peeking_take_while` iterator adaptor method.
+
+The `peeking_take_while` method is very similar to `take_while`, but behaves
+differently when used with a borrowed iterator (perhaps returned by
+`Iterator::by_ref`).
+
+`peeking_take_while` peeks at the next item in the iterator and runs the
+predicate on that peeked item. This avoids consuming the first item yielded by
+the underlying iterator for which the predicate returns `false`. On the other
+hand, `take_while` will consume that first item for which the predicate returns
+`false`, and it will be lost.
+
+```rust
+extern crate peeking_take_while;
+
+// Bring the `peeking_take_while` method for peekable iterators into
+// scope.
+use peeking_take_while::PeekableExt;
+
+// Let's say we have two collections we want to iterate through: `xs` and
+// `ys`. We want to perform one operation on all the leading contiguous
+// elements that match some predicate, and a different thing with the rest of
+// the elements. With the `xs`, we will use the normal `take_while`. With the
+// `ys`, we will use `peeking_take_while`.
+
+let xs: Vec<u8> = (0..100).collect();
+let ys = xs.clone();
+
+let mut iter_xs = xs.into_iter();
+let mut iter_ys = ys.into_iter().peekable();
+
+{
+    // Let's do one thing with all the items that are less than 10.
+
+    let xs_less_than_ten = iter_xs.by_ref().take_while(|x| *x < 10);
+    for x in xs_less_than_ten {
+        do_things_with(x);
+    }
+
+    let ys_less_than_ten = iter_ys.by_ref().peeking_take_while(|y| *y < 10);
+    for y in ys_less_than_ten {
+        do_things_with(y);
+    }
+}
+
+// And now we will do some other thing with the items that are greater than
+// or equal to 10.
+
+// ...except, when using plain old `take_while` we lost 10!
+assert_eq!(iter_xs.next(), Some(11));
+
+// However, when using `peeking_take_while` we did not! Great!
+assert_eq!(iter_ys.next(), Some(10));
+```
new file mode 100644
--- /dev/null
+++ b/third_party/rust/peeking_take_while/src/lib.rs
@@ -0,0 +1,117 @@
+//! # `peeking_take_while`
+//!
+//! Provides the `peeking_take_while` iterator adaptor method.
+//!
+//! The `peeking_take_while` method is very similar to `take_while`, but behaves
+//! differently when used with a borrowed iterator (perhaps returned by
+//! `Iterator::by_ref`).
+//!
+//! `peeking_take_while` peeks at the next item in the iterator and runs the
+//! predicate on that peeked item. This avoids consuming the first item yielded
+//! by the underlying iterator for which the predicate returns `false`. On the
+//! other hand, `take_while` will consume that first item for which the
+//! predicate returns `false`, and it will be lost.
+//!
+//! ```
+//! extern crate peeking_take_while;
+//!
+//! // Bring the `peeking_take_while` method for peekable iterators into
+//! // scope.
+//! use peeking_take_while::PeekableExt;
+//!
+//! # fn main() {
+//! // Let's say we have two collections we want to iterate through: `xs` and
+//! // `ys`. We want to perform one operation on all the leading contiguous
+//! // elements that match some predicate, and a different thing with the rest of
+//! // the elements. With the `xs`, we will use the normal `take_while`. With the
+//! // `ys`, we will use `peeking_take_while`.
+//!
+//! let xs: Vec<u8> = (0..100).collect();
+//! let ys = xs.clone();
+//!
+//! let mut iter_xs = xs.into_iter();
+//! let mut iter_ys = ys.into_iter().peekable();
+//!
+//! {
+//!     // Let's do one thing with all the items that are less than 10.
+//! #   fn do_things_with<T>(_: T) {}
+//!
+//!     let xs_less_than_ten = iter_xs.by_ref().take_while(|x| *x < 10);
+//!     for x in xs_less_than_ten {
+//!         do_things_with(x);
+//!     }
+//!
+//!     let ys_less_than_ten = iter_ys.by_ref().peeking_take_while(|y| *y < 10);
+//!     for y in ys_less_than_ten {
+//!         do_things_with(y);
+//!     }
+//! }
+//!
+//! // And now we will do some other thing with the items that are greater than
+//! // or equal to 10.
+//!
+//! // ...except, when using plain old `take_while` we lost 10!
+//! assert_eq!(iter_xs.next(), Some(11));
+//!
+//! // However, when using `peeking_take_while` we did not! Great!
+//! assert_eq!(iter_ys.next(), Some(10));
+//! # }
+//! ```
+
+use std::iter::Peekable;
+
+/// The iterator returned by `peeking_take_while`.
+///
+/// See the [module documentation](./index.html) for details.
+pub struct PeekingTakeWhile<'a, I, P>
+    where I: 'a + Iterator
+{
+    iter: &'a mut Peekable<I>,
+    predicate: P,
+}
+
+impl<'a, I, P> Iterator for PeekingTakeWhile<'a, I, P>
+    where I: Iterator,
+          I::Item: ::std::fmt::Debug,
+          P: FnMut(&<I as Iterator>::Item) -> bool
+{
+    type Item = <I as Iterator>::Item;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        let predicate = &mut self.predicate;
+        if self.iter.peek().map_or(false, |x| !(predicate)(x)) {
+            None
+        } else {
+            self.iter.next()
+        }
+    }
+}
+
+/// The `Iterator` extension trait that provides the `peeking_take_while`
+/// method.
+///
+/// See the [module documentation](./index.html) for details.
+pub trait PeekableExt<'a, I>: Iterator
+    where I: 'a + Iterator
+{
+    /// The `Iterator` extension trait that provides the `peeking_take_while`
+    /// method.
+    ///
+    /// See the [module documentation](./index.html) for details.
+    fn peeking_take_while<P>(&'a mut self, predicate: P) -> PeekingTakeWhile<'a, I, P>
+        where Self: Sized,
+              P: FnMut(&<Self as Iterator>::Item) -> bool;
+}
+
+impl<'a, I> PeekableExt<'a, I> for Peekable<I>
+    where I: 'a + Iterator
+{
+    fn peeking_take_while<P>(&'a mut self, predicate: P) -> PeekingTakeWhile<I, P>
+        where P: FnMut(&<Self as Iterator>::Item) -> bool
+    {
+        PeekingTakeWhile {
+            iter: self,
+            predicate: predicate,
+        }
+    }
+}
--- a/toolkit/library/gtest/rust/Cargo.lock
+++ b/toolkit/library/gtest/rust/Cargo.lock
@@ -65,27 +65,28 @@ source = "registry+https://github.com/ru
 dependencies = [
  "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "bindgen"
-version = "0.25.0"
+version = "0.25.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "aster 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "cexpr 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "clang-sys 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clang-sys 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "clap 2.20.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "env_logger 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "quasi 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "quasi_codegen 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "syntex_syntax 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "bit-set"
@@ -130,17 +131,17 @@ dependencies = [
 
 [[package]]
 name = "cfg-if"
 version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "clang-sys"
-version = "0.17.0"
+version = "0.18.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
  "libloading 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -562,16 +563,21 @@ dependencies = [
 ]
 
 [[package]]
 name = "pdqsort"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
+name = "peeking_take_while"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
 name = "phf"
 version = "0.7.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -800,17 +806,17 @@ source = "registry+https://github.com/ru
 
 [[package]]
 name = "style"
 version = "0.0.1"
 dependencies = [
  "app_units 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "arrayvec 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "bindgen 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bindgen 0.25.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "bit-vec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "cssparser 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1131,26 +1137,26 @@ dependencies = [
 "checksum aho-corasick 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0638fd549427caa90c499814196d1b9e3725eb4d15d7339d6de073a680ed0ca2"
 "checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6"
 "checksum app_units 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c89beb28482985f88b312de4021d748f45b3eecec6cc8dbaf0c2b3c3d1ce6da5"
 "checksum arrayvec 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "699e63a93b79d717e8c3b5eb1b28b7780d0d6d9e59a72eb769291c83b0c8dc67"
 "checksum aster 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ccfdf7355d9db158df68f976ed030ab0f6578af811f5a7bb6dcf221ec24e0e0"
 "checksum atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb2dcb6e6d35f20276943cc04bb98e538b348d525a04ac79c10021561d202f21"
 "checksum binary-space-partition 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88ceb0d16c4fd0e42876e298d7d3ce3780dd9ebdcbe4199816a32c77e08597ff"
 "checksum bincode 1.0.0-alpha6 (registry+https://github.com/rust-lang/crates.io-index)" = "fb0cdeac1c5d567fdb487ae5853c024e4acf1ea85ba6a6552fe084e0805fea5d"
-"checksum bindgen 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ccaf8958532d7e570e905266ee2dc1094c3e5c3c3cfc2c299368747a30a5e654"
+"checksum bindgen 0.25.1 (registry+https://github.com/rust-lang/crates.io-index)" = "708a688675f9d2e7c73018e17f5997beacc9a5ca87a0cb60c13093915facda32"
 "checksum bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9bf6104718e80d7b26a68fdbacff3481cfc05df670821affc7e9cbc1884400c"
 "checksum bit-vec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5b97c2c8e8bbb4251754f559df8af22fb264853c7d009084a576cdf12565089d"
 "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
 "checksum bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1370e9fc2a6ae53aea8b7a5110edbd08836ed87c88736dfabccade1c2b44bff4"
 "checksum bitreader 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "80b13e2ab064ff3aa0bdbf1eff533f9822dc37899821f5f98c67f263eab51707"
 "checksum byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c40977b0ee6b9885c9013cd41d9feffdd22deb3bb4dc3a71d901cc7a77de18c8"
 "checksum cexpr 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "393a5f0088efbe41f9d1fcd062f24e83c278608420e62109feb2c8abee07de7d"
 "checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c"
-"checksum clang-sys 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "33d47b0ea88a529a570490efbb79403e416e89864ce8a96bf23e2a0f23d7e9eb"
+"checksum clang-sys 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff7c2d1502c65748c7221f43ce670b3ba5c697acebfeb85a580827daca6975fc"
 "checksum clap 2.20.5 (registry+https://github.com/rust-lang/crates.io-index)" = "7db281b0520e97fbd15cd615dcd8f8bcad0c26f5f7d5effe705f090f39e9a758"
 "checksum core-foundation 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f51ce3b8ebe311c56de14231eb57572c15abebd2d32b3bcb99bcdb9c101f5ac3"
 "checksum core-foundation-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "41115a6aa5d3e1e5ef98148373f25971d1fad53818553f216495f9e67e90a624"
 "checksum core-graphics 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ead017dcf77f503dc991f6b52de6084eeea60a94b0a652baa9bf88654a28e83f"
 "checksum core-text 4.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0e9719616a10f717628e074744f8c55df7b450f7a34d29c196d14f4498aad05d"
 "checksum cssparser 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)" = "88dc7bd2a41b9c6c66456ac709d9efead1deb390d2c252c59e0ddfff9cdf0c94"
 "checksum cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "079adec4af52bb5275eadd004292028c79eb3c5f5b4ee8086a36d4197032f6df"
 "checksum deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1614659040e711785ed8ea24219140654da1729f3ec8a47a9719d041112fe7bf"
@@ -1182,16 +1188,17 @@ dependencies = [
 "checksum num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "e1cbfa3781f3fe73dc05321bed52a06d2d491eaa764c52335cf4399f046ece99"
 "checksum num_cpus 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a225d1e2717567599c24f88e49f00856c6e825a12125181ee42c4257e3688d39"
 "checksum odds 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)" = "c3df9b730298cea3a1c3faa90b7e2f9df3a9c400d0936d6015e6165734eefcba"
 "checksum ordered-float 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "da12c96037889ae0be29dd2bdd260e5a62a7df24e6466d5a15bb8131c1c200a8"
 "checksum owning_ref 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9d52571ddcb42e9c900c901a18d8d67e393df723fcd51dd59c5b1a85d0acb6cc"
 "checksum parking_lot 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "fa12d706797d42551663426a45e2db2e0364bd1dbf6aeada87e89c5f981f43e9"
 "checksum parking_lot_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "56a19dcbb5d1e32b6cccb8a9aa1fc2a38418c8699652e735e2bf391a3dc0aa16"
 "checksum pdqsort 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ceca1642c89148ca05611cc775a0c383abef355fc4907c4e95f49f7b09d6287c"
+"checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
 "checksum phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "cb325642290f28ee14d8c6201159949a872f220c62af6e110a56ea914fbe42fc"
 "checksum phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d62594c0bb54c464f633175d502038177e90309daf2e0158be42ed5f023ce88f"
 "checksum phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6b07ffcc532ccc85e3afc45865469bf5d9e4ef5bfcf9622e3cfe80c2d275ec03"
 "checksum phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "07e24b0ca9643bdecd0632f2b3da6b1b89bbb0030e0b992afc1113b23a7bc2f2"
 "checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
 "checksum plane-split 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8b3624c9e5e728dcc6347bde5762406b0f0707bea527d585e8f7b6ac44fdd33a"
 "checksum precomputed-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf1fc3616b3ef726a847f2cd2388c646ef6a1f1ba4835c2629004da48184150"
 "checksum procedural-masquerade 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9f566249236c6ca4340f7ca78968271f0ed2b0f234007a61b66f9ecd0af09260"
--- a/toolkit/library/rust/Cargo.lock
+++ b/toolkit/library/rust/Cargo.lock
@@ -63,27 +63,28 @@ source = "registry+https://github.com/ru
 dependencies = [
  "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "bindgen"
-version = "0.25.0"
+version = "0.25.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "aster 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "cexpr 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "clang-sys 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clang-sys 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "clap 2.20.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "env_logger 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "quasi 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "quasi_codegen 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "syntex_syntax 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "bit-set"
@@ -128,17 +129,17 @@ dependencies = [
 
 [[package]]
 name = "cfg-if"
 version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "clang-sys"
-version = "0.17.0"
+version = "0.18.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
  "libloading 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -549,16 +550,21 @@ dependencies = [
 ]
 
 [[package]]
 name = "pdqsort"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
+name = "peeking_take_while"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
 name = "phf"
 version = "0.7.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -787,17 +793,17 @@ source = "registry+https://github.com/ru
 
 [[package]]
 name = "style"
 version = "0.0.1"
 dependencies = [
  "app_units 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "arrayvec 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "bindgen 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bindgen 0.25.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "bit-vec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "cssparser 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1118,26 +1124,26 @@ dependencies = [
 "checksum aho-corasick 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0638fd549427caa90c499814196d1b9e3725eb4d15d7339d6de073a680ed0ca2"
 "checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6"
 "checksum app_units 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c89beb28482985f88b312de4021d748f45b3eecec6cc8dbaf0c2b3c3d1ce6da5"
 "checksum arrayvec 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "699e63a93b79d717e8c3b5eb1b28b7780d0d6d9e59a72eb769291c83b0c8dc67"
 "checksum aster 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ccfdf7355d9db158df68f976ed030ab0f6578af811f5a7bb6dcf221ec24e0e0"
 "checksum atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb2dcb6e6d35f20276943cc04bb98e538b348d525a04ac79c10021561d202f21"
 "checksum binary-space-partition 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88ceb0d16c4fd0e42876e298d7d3ce3780dd9ebdcbe4199816a32c77e08597ff"
 "checksum bincode 1.0.0-alpha6 (registry+https://github.com/rust-lang/crates.io-index)" = "fb0cdeac1c5d567fdb487ae5853c024e4acf1ea85ba6a6552fe084e0805fea5d"
-"checksum bindgen 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ccaf8958532d7e570e905266ee2dc1094c3e5c3c3cfc2c299368747a30a5e654"
+"checksum bindgen 0.25.1 (registry+https://github.com/rust-lang/crates.io-index)" = "708a688675f9d2e7c73018e17f5997beacc9a5ca87a0cb60c13093915facda32"
 "checksum bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9bf6104718e80d7b26a68fdbacff3481cfc05df670821affc7e9cbc1884400c"
 "checksum bit-vec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5b97c2c8e8bbb4251754f559df8af22fb264853c7d009084a576cdf12565089d"
 "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
 "checksum bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1370e9fc2a6ae53aea8b7a5110edbd08836ed87c88736dfabccade1c2b44bff4"
 "checksum bitreader 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "80b13e2ab064ff3aa0bdbf1eff533f9822dc37899821f5f98c67f263eab51707"
 "checksum byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c40977b0ee6b9885c9013cd41d9feffdd22deb3bb4dc3a71d901cc7a77de18c8"
 "checksum cexpr 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "393a5f0088efbe41f9d1fcd062f24e83c278608420e62109feb2c8abee07de7d"
 "checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c"
-"checksum clang-sys 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "33d47b0ea88a529a570490efbb79403e416e89864ce8a96bf23e2a0f23d7e9eb"
+"checksum clang-sys 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff7c2d1502c65748c7221f43ce670b3ba5c697acebfeb85a580827daca6975fc"
 "checksum clap 2.20.5 (registry+https://github.com/rust-lang/crates.io-index)" = "7db281b0520e97fbd15cd615dcd8f8bcad0c26f5f7d5effe705f090f39e9a758"
 "checksum core-foundation 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f51ce3b8ebe311c56de14231eb57572c15abebd2d32b3bcb99bcdb9c101f5ac3"
 "checksum core-foundation-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "41115a6aa5d3e1e5ef98148373f25971d1fad53818553f216495f9e67e90a624"
 "checksum core-graphics 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ead017dcf77f503dc991f6b52de6084eeea60a94b0a652baa9bf88654a28e83f"
 "checksum core-text 4.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0e9719616a10f717628e074744f8c55df7b450f7a34d29c196d14f4498aad05d"
 "checksum cssparser 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)" = "88dc7bd2a41b9c6c66456ac709d9efead1deb390d2c252c59e0ddfff9cdf0c94"
 "checksum cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "079adec4af52bb5275eadd004292028c79eb3c5f5b4ee8086a36d4197032f6df"
 "checksum deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1614659040e711785ed8ea24219140654da1729f3ec8a47a9719d041112fe7bf"
@@ -1169,16 +1175,17 @@ dependencies = [
 "checksum num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "e1cbfa3781f3fe73dc05321bed52a06d2d491eaa764c52335cf4399f046ece99"
 "checksum num_cpus 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a225d1e2717567599c24f88e49f00856c6e825a12125181ee42c4257e3688d39"
 "checksum odds 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)" = "c3df9b730298cea3a1c3faa90b7e2f9df3a9c400d0936d6015e6165734eefcba"
 "checksum ordered-float 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "da12c96037889ae0be29dd2bdd260e5a62a7df24e6466d5a15bb8131c1c200a8"
 "checksum owning_ref 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9d52571ddcb42e9c900c901a18d8d67e393df723fcd51dd59c5b1a85d0acb6cc"
 "checksum parking_lot 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "fa12d706797d42551663426a45e2db2e0364bd1dbf6aeada87e89c5f981f43e9"
 "checksum parking_lot_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "56a19dcbb5d1e32b6cccb8a9aa1fc2a38418c8699652e735e2bf391a3dc0aa16"
 "checksum pdqsort 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ceca1642c89148ca05611cc775a0c383abef355fc4907c4e95f49f7b09d6287c"
+"checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
 "checksum phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "cb325642290f28ee14d8c6201159949a872f220c62af6e110a56ea914fbe42fc"
 "checksum phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d62594c0bb54c464f633175d502038177e90309daf2e0158be42ed5f023ce88f"
 "checksum phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6b07ffcc532ccc85e3afc45865469bf5d9e4ef5bfcf9622e3cfe80c2d275ec03"
 "checksum phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "07e24b0ca9643bdecd0632f2b3da6b1b89bbb0030e0b992afc1113b23a7bc2f2"
 "checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
 "checksum plane-split 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8b3624c9e5e728dcc6347bde5762406b0f0707bea527d585e8f7b6ac44fdd33a"
 "checksum precomputed-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf1fc3616b3ef726a847f2cd2388c646ef6a1f1ba4835c2629004da48184150"
 "checksum procedural-masquerade 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9f566249236c6ca4340f7ca78968271f0ed2b0f234007a61b66f9ecd0af09260"