No bug - Revendor rust dependencies
authorServo VCS Sync <servo-vcs-sync@mozilla.com>
Fri, 28 Jul 2017 06:37:28 +0000
changeset 420255 affa66a29e556abeb3ce0370c31ce68c08d7accd
parent 420254 d6e31d250e17daefdeae7761dede122ad991aa1d
child 420256 eaaaa3adbe3ca3b13cdffa833da49dfd6eb4bcdd
push id7566
push usermtabara@mozilla.com
push dateWed, 02 Aug 2017 08:25:16 +0000
treeherdermozilla-beta@86913f512c3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone56.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/.travis.yml
third_party/rust/bindgen/CONTRIBUTING.md
third_party/rust/bindgen/Cargo.toml
third_party/rust/bindgen/README.md
third_party/rust/bindgen/appveyor.yml
third_party/rust/bindgen/book/src/cpp.md
third_party/rust/bindgen/book/src/introduction.md
third_party/rust/bindgen/book/src/requirements.md
third_party/rust/bindgen/book/src/tutorial-0.md
third_party/rust/bindgen/book/src/tutorial-1.md
third_party/rust/bindgen/book/src/tutorial-3.md
third_party/rust/bindgen/book/src/tutorial-4.md
third_party/rust/bindgen/book/src/tutorial-5.md
third_party/rust/bindgen/book/src/tutorial-6.md
third_party/rust/bindgen/ci/assert-docs.sh
third_party/rust/bindgen/ci/assert-no-diff.bat
third_party/rust/bindgen/ci/deploy-book.sh
third_party/rust/bindgen/ci/no-includes.sh
third_party/rust/bindgen/ci/test-book.sh
third_party/rust/bindgen/ci/test.bat
third_party/rust/bindgen/ci/test.sh
third_party/rust/bindgen/src/codegen/helpers.rs
third_party/rust/bindgen/src/codegen/mod.rs
third_party/rust/bindgen/src/ir/analysis/derive_debug.rs
third_party/rust/bindgen/src/ir/analysis/has_vtable.rs
third_party/rust/bindgen/src/ir/analysis/mod.rs
third_party/rust/bindgen/src/ir/analysis/template_params.rs
third_party/rust/bindgen/src/ir/comment.rs
third_party/rust/bindgen/src/ir/comp.rs
third_party/rust/bindgen/src/ir/context.rs
third_party/rust/bindgen/src/ir/derive.rs
third_party/rust/bindgen/src/ir/dot.rs
third_party/rust/bindgen/src/ir/enum_ty.rs
third_party/rust/bindgen/src/ir/function.rs
third_party/rust/bindgen/src/ir/item.rs
third_party/rust/bindgen/src/ir/layout.rs
third_party/rust/bindgen/src/ir/mod.rs
third_party/rust/bindgen/src/ir/module.rs
third_party/rust/bindgen/src/ir/named.rs
third_party/rust/bindgen/src/ir/template.rs
third_party/rust/bindgen/src/ir/traversal.rs
third_party/rust/bindgen/src/ir/ty.rs
third_party/rust/bindgen/src/lib.rs
third_party/rust/bindgen/src/main.rs
third_party/rust/bindgen/src/options.rs
third_party/rust/bindgen/src/uses.rs
third_party/rust/clang-sys/.cargo-checksum.json
third_party/rust/clang-sys/Cargo.toml
third_party/rust/clang-sys/src/lib.rs
third_party/rust/clang-sys/src/support.rs
third_party/rust/clang-sys/tests/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":"213c5948f132f0855d1efee494beb6fae1f010d25791c19c702982157961bc96",".travis.yml":"7dab433f370e5d17b6c4cdee8f4ce819ecfbef005696707fa84344c8e3acaf3f","CONTRIBUTING.md":"b732c61b6a906843e343553f3ff80b4dbcf671271dbb966ac98cdcf064fbd49d","Cargo.toml":"cc00926c2264c8e854979cd3be1f74fbc1a84dd563b6c600673c502f0b33c58c","LICENSE":"1d2e4bdb9d94ab020e9550136cae9ec73fc699c3c96a9d98078c542e9b93d294","README.md":"a9de10e2422217cb41cac812694eedc82c2c429d18721af05a38f4593d56347c","book/book.toml":"dbf931141036d1d0eb02b326f7f5d7867dd9a8f0fc49b66b8fd97e9873c08e44","book/src/SUMMARY.md":"471d2494f28b4c9c40e004ec7190479345ee2d29247b712726d8820234172dd6","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":"0d200db8c6c1cf038ac96c6a8f627b2cf473eb189df5698c9d3783ce31e67b42","book/src/tutorial-4.md":"840edccb116f59229a2132041b5ec532f903ca90ec9904a3d1b6847779e62a66","book/src/tutorial-5.md":"45a3034e2ad8d701a8cc5d2e5e34fb427486f1ebddeff3a91a9567a1b3b668d8","book/src/tutorial-6.md":"e92a5188366108495dc1e989a1ed77c31a71b09b4c3e48936c9445b49bcc466b","book/src/using-unions.md":"bcd0f5f97a199ac84df4cd4a43dc6ca17d5eff6493b90247f3425b9c2c68c1ff","book/src/whitelisting.md":"b6913e3fc43d28f504331afe4ccc3607caad9aa88d4cb627a86bdc1e72ea0175","build.rs":"5e44ce645edcd487efae5e127efe289d1216c7f55dce65d26248f61f5dde4a3a","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":"79ffe98ef68e889731e1babf63157b75587e81faf96d97ce7e8be48377bfe77e","src/codegen/error.rs":"2613af1d833377fd4a70719f4a09951d9d45dc9227827b9a2a938a1bcaaea2dd","src/codegen/helpers.rs":"4bbb92c587e881466ac4d343ada69f4a7a8edea8c484cf142664dade7c150acc","src/codegen/mod.rs":"eba368721bba59a4a30e9872ecc291e95f37ea7995e6d683e63ccaf9bae3620a","src/codegen/struct_layout.rs":"130cf8a2e1cb8348a13e05904af2300333b51bf72cd63f3ec696b768a4a6b52d","src/extra_assertions.rs":"449549c4a7a50c3f0b06332452b2fb6c9b23f31ca8e5e1656fe6c7f21e8ef7fa","src/ir/annotations.rs":"887ad7beaa43eddd60337b67951a109c2e7f51cb8e757b35cad45f744b7ba919","src/ir/comp.rs":"f0abc363566004ca53b42a714dbb6d897bb9df498c1a55684af250f2e57d6c52","src/ir/context.rs":"0487f3a4394f035a33b9d9cec6b91db71b288e97f8673a0b9d0b13596dec332f","src/ir/derive.rs":"8706a8e3c4ccd2135d0eb9ec8c0e02008609604bce42cad2974f3ca7d2ca7d91","src/ir/dot.rs":"d9b60aab08949a6d597d2fe000401c021f3cfff8805cd7ad02b8f22824e4525d","src/ir/enum_ty.rs":"cb552126907501e78a8c98a2d107c825842a45ab3fad8b656bdaf9925d0cdfd9","src/ir/function.rs":"e8fd7a2d8ee7aa89b79fbd00fa4d01898c7dc5c34bfb89b696a1b6eadc53df66","src/ir/int.rs":"b7bc19668ca6c7c084a3f8d1e07d5a980ee49c0c9a8882c3e72baab4ea7fa403","src/ir/item.rs":"68657a53b86861336cd61c9bc4beec56b64afe3afcb0b324dfc4c8a4c60a73f8","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":"e8bda175f508d484d454ce1467a3a5c2c8717fe8bdd3ae18179203e4cc0ec4e2","src/ir/traversal.rs":"02f25e1cad8f8630408a5b08aa5cc1d2dc97301455ef0fbb349f9f21d1334f2a","src/ir/ty.rs":"9929c17730794c95dfbed9ccdfb88fa2ac0b0fe679d1cb36ce7ced46206760aa","src/ir/var.rs":"0b56e6107bf96063c6a9bcb47fcbd1950147d63d242185498e95242174f083d6","src/lib.rs":"d3694acfb05368e2b770f031f7354cf4107c213b8a7df98cdcd0b0de9effafd1","src/log_stubs.rs":"6dfdd908b7c6453da416cf232893768f9480e551ca4add0858ef88bf71ee6ceb","src/main.rs":"53be7272893f3bd9b27b831ecc84ab53cc701423995b19355f99b1daa5c17471","src/options.rs":"14987a7f6360e292627e2194bbbd2bb520ff6ac2efede04a8c6e83061412c629","src/parse.rs":"6d88e1dcdb4e99f4f65629ce205c14e18097773bc938973f8e3849ba3bda4f79","src/regex_set.rs":"6c46877238c338e1fc6a35a8983db21f0711c979e44310975f60ad73a50fdbbc","src/uses.rs":"b46a9b540c39d23fa1c22c8b5325d00486348a2aec2464deada524a6b96ebec2"},"package":"04488a91af8f15eec4d88eb59e2c4e982c03ff31582acf2f5623e2e6d8ae9e0b"}
\ No newline at end of file
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".github/ISSUE_TEMPLATE.md":"952c59a2801c6e204801585704469db1af23cade4019281ba8d6027c0a03c553",".travis.yml":"fe5a4cd14f10c5d5c39ad6e22500cd0b68cfa1a5beb625d01577610100a9dfeb","CONTRIBUTING.md":"bef289580b237a158170335a998ab5d77f4e620424ce3636b0cf9fde181b1aaa","Cargo.toml":"bbae95802d3e7044687bef057a47777b409ed898cf370a40de52cb6821263a27","LICENSE":"1d2e4bdb9d94ab020e9550136cae9ec73fc699c3c96a9d98078c542e9b93d294","README.md":"8c4662f1c596d52d134cf5fa628655dc81b4259fb8e5349062eb36626d009efe","appveyor.yml":"6648e724bf3f5981ea0aa299417b3980a6dd1134cabd2ed34072759b70063d1b","book/book.toml":"dbf931141036d1d0eb02b326f7f5d7867dd9a8f0fc49b66b8fd97e9873c08e44","book/src/SUMMARY.md":"471d2494f28b4c9c40e004ec7190479345ee2d29247b712726d8820234172dd6","book/src/blacklisting.md":"a68424cc3643e06e83c5ea4efd5eb501dc64229ff9f4286b9a210a2376c20a9b","book/src/chapter_1.md":"cac4f4a3609ec22eb519b0e07d1d1bdc15ac3d741f29f9b97280f700b96ded66","book/src/command-line-usage.md":"9e3ae32cb5d893f1a93fc539149950bacdf43a18c694169fa45dfe8080617403","book/src/cpp.md":"c7926268d311239caa4475602634d609553d4a8a0e0902fcbd1762d1d405f657","book/src/customizing-generated-bindings.md":"0363ca69719c5e24d624ac3adfef71445896d3ed2b7bb3689c7905e47bdd9cdd","book/src/introduction.md":"c1b11894292f326fa492534c5a9a58b0238d05caccb3e145b70b226069ee674e","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":"f6715430e9830593501a9b8c09105058189832df1a0b4d9852400fa408069f0e","book/src/tutorial-0.md":"0343285deac4161a230450ab8e9aa825d2a42f243cb10372b2d0edef8b956c29","book/src/tutorial-1.md":"c341e519ff6f2abb55e63139e106e3161c5169b2154bf694cd9c34c7feb3a89e","book/src/tutorial-2.md":"f6c9cf4ea8e38628c15dedc0ee7f60055a2aa841e95f972465d2932bb71878ad","book/src/tutorial-3.md":"580d25d9754d540af2b7d3eb99a828555479c37a61566e21eec9a00f98f829c3","book/src/tutorial-4.md":"23e82ec5d2de96670e148e5417b61810c203603adea54aefc94a2b16d1d0ede2","book/src/tutorial-5.md":"60e7f50e9be3c7de0e096f6615815d74608afa184c649b4301d71a60c808c646","book/src/tutorial-6.md":"806238e5156b10881489bda6c5480e9bd0aa88208ef2d74dd26c18cd3d024dff","book/src/using-unions.md":"bcd0f5f97a199ac84df4cd4a43dc6ca17d5eff6493b90247f3425b9c2c68c1ff","book/src/whitelisting.md":"b6913e3fc43d28f504331afe4ccc3607caad9aa88d4cb627a86bdc1e72ea0175","build.rs":"5e44ce645edcd487efae5e127efe289d1216c7f55dce65d26248f61f5dde4a3a","ci/assert-docs.sh":"f60a78a7d6f6444389df39a070a08851c78f1b525afff3b2548e852a3ebf6dc6","ci/assert-no-diff.bat":"904a49de6ee9faf8b83cc21d958d2fb37d4b278e9fe48484320aa55f9089f032","ci/assert-no-diff.sh":"af208c40d412e2bce82ae9b4a4e52cae4ae0b4beef9f93eb825bf5d5346a70b2","ci/assert-rustfmt.sh":"b9c810e86ea6d71bce1d6bf8d896839cfe2c198338e042ebc744b75e83af1126","ci/before_install.sh":"51409851cf4e1dee27735461e77247c599e023259c3a57e82fa044f284ca8e87","ci/deploy-book.sh":"67a3df2cc39ee585a2d5353d303e452d9586bec7ea33de6b5aa4a0ecb43c136f","ci/no-includes.sh":"148b146eab4aeb11ad229e03b3d5ebd8cb56a31674df438264d1ebff2d17f52d","ci/test-book.sh":"dfbcfb1381f723b4b29634bb4033ab72ace412d0711631976897c64d57122600","ci/test.bat":"88368377f3907eb34b3693a5ddf8ff69168b17bcc6528807aaf52dc693cb3c47","ci/test.sh":"01059bf60d40053534f9606986d3f4e06e90262848c4b3114df62b7b90f84793","example-graphviz-ir.png":"e1122ab33b4c80e8c9c0cf8abea404c1192f9b2eef97f5766e86103cc95d5e01","rustfmt.toml":"c4f3b593bdd634590df22aaf7b0872244d5c2169aacd0274a05e4aca4708a8d3","src/callbacks.rs":"e0d36d30adac8a4eaab64f0a9df0ab29026fcd5f5c5588bdeb2ad762e4c024ad","src/clang.rs":"79ffe98ef68e889731e1babf63157b75587e81faf96d97ce7e8be48377bfe77e","src/codegen/error.rs":"2613af1d833377fd4a70719f4a09951d9d45dc9227827b9a2a938a1bcaaea2dd","src/codegen/helpers.rs":"501838ff8da3c51c90eefdbee0228e321782e755201147b0d8ed78c2f59b29d1","src/codegen/mod.rs":"1f7ae949d425e3724f62de144b483f0f4257c02071ca00623798170b5dbf9745","src/codegen/struct_layout.rs":"130cf8a2e1cb8348a13e05904af2300333b51bf72cd63f3ec696b768a4a6b52d","src/extra_assertions.rs":"449549c4a7a50c3f0b06332452b2fb6c9b23f31ca8e5e1656fe6c7f21e8ef7fa","src/ir/analysis/derive_debug.rs":"18c9c16f233c2dabed9b5d85a07c2e6c884b318336996d217e1a6b14b023a54a","src/ir/analysis/has_vtable.rs":"6f49e17b1b40f8683d21a89725aec48f9fe4417361a55cf302e568eecbe2d35d","src/ir/analysis/mod.rs":"5758a40600e19278bb7dc4238f7e490971fa5aa83ade9497924fd722da9bf315","src/ir/analysis/template_params.rs":"b74243aab14f50d8a765d9e30f48e8c58ba340e4b4bfb7db9c87f1123842e3aa","src/ir/annotations.rs":"887ad7beaa43eddd60337b67951a109c2e7f51cb8e757b35cad45f744b7ba919","src/ir/comment.rs":"564a9fbf4bd7bf03ecf93104109ef66ed501abeaf4e4784b1d14083df6cade3b","src/ir/comp.rs":"5146cede0fdc3747c4ab12b4665d39b8ab482c0308577582013d878dee595b5f","src/ir/context.rs":"f8cfdaf8f53811eebfe52b9966b70a3780f12ca2baebce08e393178622d108ac","src/ir/derive.rs":"e4e86d86edc957eb38d310852e49e1a160bf4fdd13a70a664373c8a343705b62","src/ir/dot.rs":"79af769bff3b7c8b5c58ee73286429bcc8b9963526e42257cc61ca9a2a5eb4e9","src/ir/enum_ty.rs":"64ec618b9914aac83351624ffb9219e089dafa2959b4e896160f7f30df9e29c4","src/ir/function.rs":"bf374db02a5086b0dfd91fbc17d0b283cb057857dd13d5d9fde1dbd33aad47ef","src/ir/int.rs":"b7bc19668ca6c7c084a3f8d1e07d5a980ee49c0c9a8882c3e72baab4ea7fa403","src/ir/item.rs":"136bd52e1179349c24202d2745330d29d1ad9d1afe891cf149475ba1d6cf8d07","src/ir/item_kind.rs":"64b8b5bede6dfe950ceb15da1aabf888707eeb5883df9213f05ee47797bfb84f","src/ir/layout.rs":"58df6436c7170ab7b2bde2afe4760f6dfc35a6ef3edb50290fbd3a8ea0248453","src/ir/mod.rs":"2eae90f207fad2e45957ec9287064992a419e3fc916aba84faff2ea25cbeb5ee","src/ir/module.rs":"5f33c7bd01891ece61d946c6052b96a8127e3811616f3e698fc220716234ca6c","src/ir/objc.rs":"353be93027d74ad102ac3b0ef8754dd1258a400dcf7d361fa224fdf1ab973c56","src/ir/template.rs":"5650b957ceff3caef4d75ad5c1e5014a07ae3ccb6edd1712babbd543e192f20a","src/ir/traversal.rs":"1b9abed7bcc82f85c18d36dd475a5615984ff00588468ab81f232902f93ec423","src/ir/ty.rs":"8550883f2f65b4e113fc7beefcd5f6e1d701a9e58cc92bae4356d6eeadd69727","src/ir/var.rs":"0b56e6107bf96063c6a9bcb47fcbd1950147d63d242185498e95242174f083d6","src/lib.rs":"ca18b1e54f8be6c32030c15444f52556758e0b5c0e5048ad9389aa1cbffabd95","src/log_stubs.rs":"6dfdd908b7c6453da416cf232893768f9480e551ca4add0858ef88bf71ee6ceb","src/main.rs":"995b35df006ba97d882aa6de91ba42a616314a98687a2ea4f8bbff0669a54f54","src/options.rs":"a0ecd0eb1069df3af236fb5e9a9c9611ed1949321243aaee9e4e257c72ffd8c2","src/parse.rs":"6d88e1dcdb4e99f4f65629ce205c14e18097773bc938973f8e3849ba3bda4f79","src/regex_set.rs":"6c46877238c338e1fc6a35a8983db21f0711c979e44310975f60ad73a50fdbbc","src/uses.rs":"16841e43290424f814a4cb119b782f6987e854429f483ae8001525e3f3620958"},"package":"0c338079dafc81bef7d581f494b906603d12359c4306979eae6ca081925a4984"}
\ 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,12 +1,25 @@
+<!-- Thanks for filing a bindgen issue! We appreciate it :-) -->
+
 ### Input C/C++ Header
 
 ```C++
-// Insert your (minimal) C/C++ header here.
+// Insert your minimal C or C++ header here.
+//
+// It should *NOT* have any `#include`s! Not all systems have the same header
+// files, and therefore any `#include` harms reproducibility. Additionally,
+// the test case isn't minimal since the included file almost assuredly
+// contains things that aren't necessary to reproduce the bug, and makes
+// tracking it down much more difficult.
+//
+// Use the `--dump-preprocessed-input` flag or the
+// `bindgen::Builder::dump_preprocessed_input` method to make your test case
+// standalone and without `#include`s, and then use C-Reduce to minimize it:
+// https://github.com/rust-lang-nursery/rust-bindgen/blob/master/CONTRIBUTING.md#using-creduce-to-minimize-test-cases
 ```
 
 ### Bindgen Invocation
 
 <!-- Place either the `bindgen::Builder` or the command line flags used here. -->
 
 ```Rust
 bindgen::Builder::default()
@@ -41,19 +54,8 @@ Insert compilation errors generated when
 
 ### Expected Results
 
 <!--
 Replace this with a description of what you expected instead of the actual
 results. The more precise, the better! For example, if a struct in the generated
 bindings is missing a field that exists in the C/C++ struct, note that here.
 -->
-
-### `RUST_LOG=bindgen` Output
-
-<details>
-
-```
-Insert debug logging when running bindgen with the `RUST_LOG=bindgen` environment
-variable set.
-```
-
-</details>
--- a/third_party/rust/bindgen/.travis.yml
+++ b/third_party/rust/bindgen/.travis.yml
@@ -37,14 +37,12 @@ script:
   # - ./ci/assert-rustfmt.sh
   - BINDGEN_FEATURES="$BINDGEN_FEATURES" ./ci/assert-docs.sh
   - BINDGEN_FEATURES="$BINDGEN_FEATURES" ./ci/test.sh
   - ./ci/test-book.sh
 
 after_success:
   - test "$TRAVIS_PULL_REQUEST" == "false" &&
     test "$TRAVIS_BRANCH" == "master" &&
-    test "$BINDGEN_FEATURES" == "" &&
-    test "$LLVM_VERSION" == "3.9.0" &&
     ./ci/deploy-book.sh
 
 notifications:
   webhooks: http://build.servo.org:54856/travis
--- a/third_party/rust/bindgen/CONTRIBUTING.md
+++ b/third_party/rust/bindgen/CONTRIBUTING.md
@@ -42,19 +42,19 @@ issue, provide us with:
 * A (preferably reduced) C/C++ header file that reproduces the issue
 * The `bindgen` flags used to reproduce the issue with the header file
 * The expected `bindgen` output
 * The actual `bindgen` output
 * The [debugging logs](#logs) generated when running `bindgen` on this testcase
 
 ## Looking to Start Contributing to `bindgen`?
 
-* [Issues labeled "easy"](https://github.com/servo/rust-bindgen/issues?q=is%3Aopen+is%3Aissue+label%3AE-easy)
-* [Issues labeled "less easy"](https://github.com/servo/rust-bindgen/issues?q=is%3Aopen+is%3Aissue+label%3AE-less-easy)
-* Still can't find something to work on? [Drop a comment here](https://github.com/servo/rust-bindgen/issues/747)
+* [Issues labeled "easy"](https://github.com/rust-lang-nursery/rust-bindgen/issues?q=is%3Aopen+is%3Aissue+label%3AE-easy)
+* [Issues labeled "less easy"](https://github.com/rust-lang-nursery/rust-bindgen/issues?q=is%3Aopen+is%3Aissue+label%3AE-less-easy)
+* Still can't find something to work on? [Drop a comment here](https://github.com/rust-lang-nursery/rust-bindgen/issues/747)
 
 ## Building
 
 To build the `bindgen` library and the `bindgen` executable:
 
 ```
 $ cargo build
 ```
@@ -267,24 +267,26 @@ 2. A script to act as a predicate script
    trying to isolate occurred.
 
 With those two things in hand, running `creduce` looks like this:
 
     $ creduce ./predicate.sh ./isolated_test_case.h
 
 ### Isolating Your Test Case
 
-Use the `-save-temps` flag to make Clang spit out its intermediate
-representations when compiling the test case into an object file.
+If you're using `bindgen` as a command line tool, pass
+`--dump-preprocessed-input` flag.
 
-    $ clang[++ -x c++ --std=c++14] -save-temps -c my_test_case.h
+If you're using `bindgen` as a Rust library, invoke the
+`bindgen::Builder::dump_preprocessed_input` method where you call
+`bindgen::Builder::generate`.
 
-There should now be a `my_test_case.ii` file, which is the results after the C
-pre-processor has processed all the `#include`s, `#define`s, and `#ifdef`s. This
-is generally what we're looking for.
+Afterwards, there should be a `__bindgen.i` or `__bindgen.ii` file containing
+the combined and preprocessed input headers, which is usable as an isolated,
+standalone test case.
 
 ### Writing a Predicate Script
 
 Writing a `predicate.sh` script for a `bindgen` test case is fairly
 straightforward. One potential gotcha is that `creduce` can and will attempt to
 reduce test cases into invalid C/C++ code. That might be useful for C/C++
 compilers, but we generally only care about valid C/C++ input headers.
 
--- a/third_party/rust/bindgen/Cargo.toml
+++ b/third_party/rust/bindgen/Cargo.toml
@@ -7,89 +7,89 @@
 #
 # If you believe there's an error in this file please file an
 # issue against the rust-lang/cargo repository. If you're
 # editing this file be aware that the upstream Cargo.toml
 # will likely look very different (and much more reasonable)
 
 [package]
 name = "bindgen"
-version = "0.26.1"
+version = "0.29.0"
 authors = ["Jyun-Yan You <jyyou.tw@gmail.com>", "Emilio Cobos Álvarez <emilio@crisal.io>", "Nick Fitzgerald <fitzgen@gmail.com>", "The Servo project developers"]
 build = "build.rs"
 exclude = ["bindgen-integration", "ci", "tests/**", "*.orig"]
 description = "Automatically generates Rust FFI bindings to C and C++ libraries."
 documentation = "https://docs.rs/bindgen"
 readme = "README.md"
 keywords = ["bindings", "ffi", "code-generation"]
 categories = ["external-ffi-bindings", "development-tools::ffi"]
 license = "BSD-3-Clause"
-repository = "https://github.com/servo/rust-bindgen"
+repository = "https://github.com/rust-lang-nursery/rust-bindgen"
 
 [lib]
 path = "src/lib.rs"
 
 [[bin]]
 name = "bindgen"
 path = "src/main.rs"
 doc = false
+[dependencies.clap]
+version = "2"
+
+[dependencies.peeking_take_while]
+version = "0.1.2"
+
+[dependencies.cfg-if]
+version = "0.1.0"
+
+[dependencies.regex]
+version = "0.2"
+
+[dependencies.clang-sys]
+version = "0.19.0"
+features = ["runtime", "clang_3_9"]
+
 [dependencies.lazy_static]
 version = "0.2.1"
 
+[dependencies.syntex_syntax]
+version = "0.58"
+
 [dependencies.aster]
 version = "0.41"
 features = ["with-syntex"]
 
-[dependencies.cfg-if]
-version = "0.1.0"
-
-[dependencies.clang-sys]
-version = "0.18.0"
-features = ["runtime", "clang_3_9"]
-
-[dependencies.syntex_syntax]
-version = "0.58"
-
-[dependencies.regex]
-version = "0.2"
-
-[dependencies.peeking_take_while]
-version = "0.1.2"
-
-[dependencies.cexpr]
-version = "0.2"
+[dependencies.log]
+version = "0.3"
+optional = true
 
 [dependencies.quasi]
 version = "0.32"
 features = ["with-syntex"]
 
+[dependencies.cexpr]
+version = "0.2"
+
 [dependencies.env_logger]
 version = "0.4"
 optional = true
-
-[dependencies.clap]
-version = "2"
-
-[dependencies.log]
-version = "0.3"
-optional = true
-[dev-dependencies.shlex]
-version = "0.1"
-
 [dev-dependencies.diff]
 version = "0.1"
 
 [dev-dependencies.clap]
 version = "2"
+
+[dev-dependencies.shlex]
+version = "0.1"
 [build-dependencies.quasi_codegen]
 version = "0.32"
 
 [features]
-testing_only_libclang_3_8 = []
+testing_only_extra_assertions = []
 testing_only_libclang_4 = []
-testing_only_extra_assertions = []
-static = []
-default = ["logging"]
-testing_only_libclang_3_9 = []
 testing_only_docs = []
 logging = ["env_logger", "log"]
+default = ["logging"]
+testing_only_libclang_3_8 = []
+testing_only_libclang_3_9 = []
+static = []
 [badges.travis-ci]
-repository = "servo/rust-bindgen"
+repository = "rust-lang-nursery/rust-bindgen"
--- a/third_party/rust/bindgen/README.md
+++ b/third_party/rust/bindgen/README.md
@@ -1,45 +1,43 @@
 # `bindgen`
 
 **`bindgen` automatically generates Rust FFI bindings to C and C++ libraries.**
 
-For example, given the C header `cool.h`:
+For example, given the C header `doggo.h`:
 
 ```c
-typedef struct CoolStruct {
-    int x;
-    int y;
-} CoolStruct;
+typedef struct Doggo {
+    int many;
+    char wow;
+} Doggo;
 
-void cool_function(int i, char c, CoolStruct* cs);
+void eleven_out_of_ten_majestic_af(Doggo* pupper);
 ```
 
-`bindgen` produces Rust FFI code allowing you to call into the `cool` library's
+`bindgen` produces Rust FFI code allowing you to call into the `doggo` library's
 functions and use its types:
 
 ```rust
 /* automatically generated by rust-bindgen */
 
 #[repr(C)]
-pub struct CoolStruct {
-    pub x: ::std::os::raw::c_int,
-    pub y: ::std::os::raw::c_int,
+pub struct Doggo {
+    pub many: ::std::os::raw::c_int,
+    pub wow: ::std::os::raw::c_char,
 }
 
 extern "C" {
-    pub fn cool_function(i: ::std::os::raw::c_int,
-                         c: ::std::os::raw::c_char,
-                         cs: *mut CoolStruct);
+    pub fn eleven_out_of_ten_majestic_af(pupper: *mut Doggo);
 }
 ```
 
 ## Users Guide
 
-[📚 Read the `bindgen` users guide here! 📚](https://servo.github.io/rust-bindgen)
+[📚 Read the `bindgen` users guide here! 📚](https://rust-lang-nursery.github.io/rust-bindgen)
 
 ## API Reference
 
 [API reference documentation is on docs.rs](https://docs.rs/bindgen)
 
 ## Contributing
 
 [See `CONTRIBUTING.md` for hacking on `bindgen`!](./CONTRIBUTING.md)
new file mode 100644
--- /dev/null
+++ b/third_party/rust/bindgen/appveyor.yml
@@ -0,0 +1,57 @@
+environment:
+  RUST_BACKTRACE: 1
+  RUST_CHANNEL: "%Configuration%"
+  matrix:
+  - TARGET: gnu
+    LLVM_VERSION: 3.9.0-2
+    BINDGEN_FEATURES: testing_only_libclang_3_9
+  - TARGET: gnu
+    LLVM_VERSION: 4.0.0-1
+    BINDGEN_FEATURES: testing_only_libclang_4
+  - TARGET: msvc
+    LLVM_VERSION: 3.9.0
+    BINDGEN_FEATURES: testing_only_libclang_3_9
+  - TARGET: msvc
+    LLVM_VERSION: 4.0.0
+    BINDGEN_FEATURES: testing_only_libclang_4
+
+configuration:
+- stable
+- nightly
+
+platform:
+  - x64
+  - x86
+
+branches:
+  only:
+    - master
+
+install:
+  - if %PLATFORM% == x86 (set RUST_PLATFORM=i686&set MINGW_BITS=32) else (set RUST_PLATFORM=x86_64&set MINGW_BITS=64)
+  - echo %RUST_CHANNEL%
+  - echo %RUST_PLATFORM%
+  - echo %MINGW_BITS%
+  - echo %RUST_PLATFORM%-pc-windows-%TARGET%
+  # install Rust
+  - appveyor-retry appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe
+  - rustup-init.exe -y --default-host %RUST_PLATFORM%-pc-windows-%TARGET% --default-toolchain %RUST_CHANNEL%
+  - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin
+  # install LLVM for GNU
+  - if %TARGET%==gnu set PATH=C:\msys64\mingw%MINGW_BITS%\bin;C:\msys64\usr\bin\;%PATH%
+  - if %TARGET%==gnu set "MINGW_URL=http://repo.msys2.org/mingw/%RUST_PLATFORM%/mingw-w64-%RUST_PLATFORM%"
+  - if %TARGET%==gnu set "URL_VER=%LLVM_VERSION%-any.pkg.tar.xz"
+  - if %TARGET%==gnu bash -lc "pacman -U --noconfirm $MINGW_URL-clang-$URL_VER $MINGW_URL-llvm-$URL_VER"
+  - if %TARGET%==gnu bash -lc "clang --version"
+  # install LLVM for MSVC
+  - if %TARGET%==msvc appveyor-retry appveyor DownloadFile http://releases.llvm.org/%LLVM_VERSION%/LLVM-%LLVM_VERSION%-win64.exe -FileName llvm-installer.exe
+  - if %TARGET%==msvc 7z x llvm-installer.exe -oc:\llvm-binary
+  - if %TARGET%==msvc set PATH=C:\llvm-binary\bin;%PATH%
+  - if %TARGET%==msvc where clang
+  - if %TARGET%==msvc clang --version
+
+build_script:
+  - if %TARGET%==msvc .\ci\test.bat
+  - if %TARGET%==gnu bash -lc "export BINDGEN_FEATURES=$BINDGEN_FEATURES; cd $APPVEYOR_BUILD_FOLDER; ./ci/test.sh"
+
+test: off
--- a/third_party/rust/bindgen/book/src/cpp.md
+++ b/third_party/rust/bindgen/book/src/cpp.md
@@ -12,16 +12,16 @@ which `bindgen` *should* generate opaque
 of them in a type it is generating bindings for:
 
 * Template specialization
 * Partial template specialization
 * Traits templates
 * SFINAE
 
 When passing in header files, the file will automatically be treated as C++ if
-it ends in `.hpp`. If it doesn't, adding `-x=c++` clang args can be used to
+it ends in `.hpp`. If it doesn't, adding `-x c++` clang args can be used to
 force C++ mode. You probably also want to use `-std=c++14` or similar clang args
 as well.
 
 You pretty much **must** use [whitelisting](./whitelisting.html) when working
 with C++ to avoid pulling in all of the `std::*` types, many of which `bindgen`
 cannot handle. Additionally, you may want to mark other types
 as [opaque](./opaque.html) that `bindgen` stumbles on.
--- a/third_party/rust/bindgen/book/src/introduction.md
+++ b/third_party/rust/bindgen/book/src/introduction.md
@@ -1,11 +1,11 @@
 # Introduction
 
-**[`bindgen`](https://github.com/servo/rust-bindgen) automatically generates Rust
+**[`bindgen`](https://github.com/rust-lang-nursery/rust-bindgen) automatically generates Rust
 FFI bindings to C and C++ libraries.**
 
 For example, given the C header `cool.h`:
 
 ```c
 typedef struct CoolStruct {
     int x;
     int y;
--- a/third_party/rust/bindgen/book/src/requirements.md
+++ b/third_party/rust/bindgen/book/src/requirements.md
@@ -23,17 +23,17 @@ greater.
 Download and install the official pre-built binary from
 [LLVM download page](http://releases.llvm.org/download.html).
 
 #### macOS
 
 If you use Homebrew:
 
 ```bash
-$ brew install llvm@3.9
+$ brew install llvm
 ```
 
 If you use MacPorts:
 
 ```bash
 $ port install clang-3.9
 ```
 
--- a/third_party/rust/bindgen/book/src/tutorial-0.md
+++ b/third_party/rust/bindgen/book/src/tutorial-0.md
@@ -4,9 +4,9 @@ The following tutorial is adapted from [
 
 What follows is a whirlwind introductory tutorial to using `bindgen` from inside
 `build.rs`. We'll generate bindings to `bzip2` (which is available on most
 systems) on-the-fly.
 
 [**TL;DR?** The full tutorial code is available here.][example]
 
 [tutorial]: http://fitzgeraldnick.com/2016/12/14/using-libbindgen-in-build-rs.html
-[example]: https://github.com/fitzgen/libbindgen-tutorial-bzip2-sys
+[example]: https://github.com/fitzgen/bindgen-tutorial-bzip2-sys
--- a/third_party/rust/bindgen/book/src/tutorial-1.md
+++ b/third_party/rust/bindgen/book/src/tutorial-1.md
@@ -1,9 +1,9 @@
 # Add `bindgen` as a Build Dependency
 
 Declare a build-time dependency on `bindgen` by adding it to the
 `[build-dependencies]` section of our crate's `Cargo.toml` metadata file:
 
 ```toml
 [build-dependencies]
-bindgen = "0.23"
+bindgen = "0.26.3"
 ```
--- a/third_party/rust/bindgen/book/src/tutorial-3.md
+++ b/third_party/rust/bindgen/book/src/tutorial-3.md
@@ -1,16 +1,16 @@
 # Create a `build.rs` File
 
 We create a `build.rs` file in our crate's root. Cargo will pick up on the existence of this file and compile and executed it before the rest of the crate is built.
 This can be used to generate code at compile time.
 And of course in our case, we will be generating Rust FFI
 bindings to `bzip2` at compile time. The resulting bindings will be written to
 `$OUT_DIR/bindings.rs` where `$OUT_DIR` is chosen by `cargo` and is something
-like `./target/debug/build/libbindgen-tutorial-bzip2-sys-afc7747d7eafd720/out/`.
+like `./target/debug/build/bindgen-tutorial-bzip2-sys-afc7747d7eafd720/out/`.
 
 ```rust,ignore
 extern crate bindgen;
 
 use std::env;
 use std::path::PathBuf;
 
 fn main() {
--- a/third_party/rust/bindgen/book/src/tutorial-4.md
+++ b/third_party/rust/bindgen/book/src/tutorial-4.md
@@ -13,26 +13,26 @@ include!(concat!(env!("OUT_DIR"), "/bind
 
 Because `bzip2`'s symbols do not follow Rust's style conventions, we suppress a
 bunch of warnings with a few `#![allow(...)]` pragmas.
 
 We can run `cargo build` again to check that the bindings themselves compile:
 
 ```bash
 $ cargo build
-   Compiling libbindgen-tutorial-bzip2-sys v0.1.0
+   Compiling bindgen-tutorial-bzip2-sys v0.1.0
     Finished debug [unoptimized + debuginfo] target(s) in 62.8 secs
 ```
 
 And we can run `cargo test` to verify that the layout, size, and alignment of
 our generated Rust FFI structs match what `bindgen` thinks they should be:
 
 ```bash
 $ cargo test
-   Compiling libbindgen-tutorial-bzip2-sys v0.1.0
+   Compiling bindgen-tutorial-bzip2-sys v0.1.0
     Finished debug [unoptimized + debuginfo] target(s) in 0.0 secs
      Running target/debug/deps/bzip2_sys-10413fc2af207810
 
 running 14 tests
 test bindgen_test_layout___darwin_pthread_handler_rec ... ok
 test bindgen_test_layout___sFILE ... ok
 test bindgen_test_layout___sbuf ... ok
 test bindgen_test_layout__bindgen_ty_1 ... ok
@@ -44,14 +44,14 @@ test bindgen_test_layout__opaque_pthread
 test bindgen_test_layout__opaque_pthread_mutexattr_t ... ok
 test bindgen_test_layout__opaque_pthread_once_t ... ok
 test bindgen_test_layout__opaque_pthread_rwlock_t ... ok
 test bindgen_test_layout__opaque_pthread_rwlockattr_t ... ok
 test bindgen_test_layout__opaque_pthread_t ... ok
 
 test result: ok. 14 passed; 0 failed; 0 ignored; 0 measured
 
-   Doc-tests libbindgen-tutorial-bzip2-sys
+   Doc-tests bindgen-tutorial-bzip2-sys
 
 running 0 tests
 
 test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
 ```
--- a/third_party/rust/bindgen/book/src/tutorial-5.md
+++ b/third_party/rust/bindgen/book/src/tutorial-5.md
@@ -109,19 +109,19 @@ mod tests {
 }
 ```
 
 Now let's run `cargo test` again and verify that everying is linking and binding
 properly!
 
 ```bash
 $ cargo test
-   Compiling libbindgen-tutorial-bzip2-sys v0.1.0
+   Compiling bindgen-tutorial-bzip2-sys v0.1.0
     Finished debug [unoptimized + debuginfo] target(s) in 0.54 secs
-     Running target/debug/deps/libbindgen_tutorial_bzip2_sys-1c5626bbc4401c3a
+     Running target/debug/deps/bindgen_tutorial_bzip2_sys-1c5626bbc4401c3a
 
 running 15 tests
 test bindgen_test_layout___darwin_pthread_handler_rec ... ok
 test bindgen_test_layout___sFILE ... ok
 test bindgen_test_layout___sbuf ... ok
 test bindgen_test_layout__bindgen_ty_1 ... ok
 test bindgen_test_layout__bindgen_ty_2 ... ok
 test bindgen_test_layout__opaque_pthread_attr_t ... ok
@@ -156,14 +156,14 @@ test bindgen_test_layout__opaque_pthread
     final combined CRC = 0x47bfca17
 
     [1: huff+mtf rt+rld {0x47bfca17, 0x47bfca17}]
     combined CRCs: stored = 0x47bfca17, computed = 0x47bfca17
 test tests::round_trip_compression_decompression ... ok
 
 test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured
 
-   Doc-tests libbindgen-tutorial-bzip2-sys
+   Doc-tests bindgen-tutorial-bzip2-sys
 
 running 0 tests
 
 test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
 ```
--- a/third_party/rust/bindgen/book/src/tutorial-6.md
+++ b/third_party/rust/bindgen/book/src/tutorial-6.md
@@ -5,9 +5,9 @@ Rust-y API wrapping the raw FFI bindings
 already a [`bzip2-sys`][bz-sys] crate providing raw FFI bindings, and there is
 already a [`bzip2`][bz] crate providing a nice, safe, Rust-y API on top of the
 bindings, so we have nothing left to do here!
 
 Check out the [full code on Github!][example]
 
 [bz-sys]: https://crates.io/crates/bzip2-sys
 [bz]: https://crates.io/crates/bzip2
-[example]: https://github.com/fitzgen/libbindgen-tutorial-bzip2-sys
+[example]: https://github.com/fitzgen/bindgen-tutorial-bzip2-sys
--- a/third_party/rust/bindgen/ci/assert-docs.sh
+++ b/third_party/rust/bindgen/ci/assert-docs.sh
@@ -1,6 +1,6 @@
 #!/usr/bin/env bash
 
 set -xeu
 cd "$(dirname "$0")/.."
 
-cargo build --features "$BINDGEN_FEATURES testing_only_docs"
+cargo check --features "$BINDGEN_FEATURES testing_only_docs"
new file mode 100644
--- /dev/null
+++ b/third_party/rust/bindgen/ci/assert-no-diff.bat
@@ -0,0 +1,7 @@
+@echo off
+
+cd "%~dp0.."
+
+git add -u
+git diff @
+git diff-index --quiet HEAD
--- a/third_party/rust/bindgen/ci/deploy-book.sh
+++ b/third_party/rust/bindgen/ci/deploy-book.sh
@@ -1,15 +1,15 @@
 #!/usr/bin/env bash
 
 set -xeu
 cd "$(dirname "$0")/../book"
 
 # Ensure mdbook is installed.
-cargo install mdbook || true
+cargo install mdbook --vers "^0.0.22" || true
 export PATH="$PATH:~/.cargo/bin"
 
 # Get the git revision we are on.
 rev=$(git rev-parse --short HEAD)
 
 # Build the users guide book and go into the built book's directory.
 rm -rf ./book
 mdbook build
@@ -17,17 +17,17 @@ cd ./book
 
 # Make the built book directory a new git repo, fetch upstream, make a new
 # commit on gh-pages, and push it upstream.
 
 git init
 git config user.name "Travis CI"
 git config user.email "builds@travis-ci.org"
 
-git remote add upstream "https://$GH_TOKEN@github.com/servo/rust-bindgen.git"
+git remote add upstream "https://$GH_TOKEN@github.com/rust-lang-nursery/rust-bindgen.git"
 git fetch upstream
 git reset upstream/gh-pages
 
 touch .
 
 git add -A .
 git commit -m "Rebuild users guide at ${rev}"
 git push upstream HEAD:gh-pages
new file mode 100755
--- /dev/null
+++ b/third_party/rust/bindgen/ci/no-includes.sh
@@ -0,0 +1,23 @@
+#!/usr/bin/env bash
+
+# Don't allow any system include directives in tests.
+
+set -eu
+cd "$(dirname "$0")/.."
+
+echo "Checking for #include directives of system headers..."
+
+grep -rn '#include\s*<.*>' tests/headers || {
+    echo "Found none; OK!"
+    exit 0
+}
+
+echo "
+Found a test with an #include directive of a system header file!
+
+There is no guarantee that the system running the tests has the header
+file, let alone the same version of it that you have. Any test with such an
+include directive won't reliably produce the consistent bindings across systems.
+"
+
+exit 1
--- a/third_party/rust/bindgen/ci/test-book.sh
+++ b/third_party/rust/bindgen/ci/test-book.sh
@@ -1,10 +1,10 @@
 #!/usr/bin/env bash
 
 set -xeu
 cd "$(dirname "$0")/../book"
 
-cargo install mdbook || true
+cargo install mdbook --vers "^0.0.22" || true
 export PATH="$PATH:~/.cargo/bin"
 
 mdbook build
 mdbook test
new file mode 100644
--- /dev/null
+++ b/third_party/rust/bindgen/ci/test.bat
@@ -0,0 +1,49 @@
+@echo off
+
+cd "%~dp0.."
+
+set RUST_BACKTRACE=1
+
+if not defined BINDGEN_FEATURES (
+  echo Environment variable BINDGEN_FEATURES must be defined.
+  exit /B 1
+)
+
+findstr /r /c:"#include *<.*>" tests\headers\* >nul 2>&1 && (
+  echo Found a test with an #include directive of a system header file!
+  echo.
+  echo There is no guarantee that the system running the tests has the header
+  echo file, let alone the same version of it that you have. Any test with such an
+  echo include directive won't reliably produce the consistent bindings across systems.
+  exit /B 1
+) || (
+  echo Found none. OK!
+  set ERRORLEVEL=0
+)
+
+@echo on
+
+::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%" || exit /b 1
+call .\ci\assert-no-diff.bat
+
+cargo test --features "%BINDGEN_FEATURES% testing_only_extra_assertions" || exit /b 1
+call .\ci\assert-no-diff.bat
+
+cargo test --release --features "%BINDGEN_FEATURES% testing_only_extra_assertions" || exit /b 1
+call .\ci\assert-no-diff.bat
+
+::Now test the expectations' size and alignment tests.
+
+pushd tests\expectations
+cargo test || exit /b 1
+cargo test --release || exit /b 1
+popd
+
+::And finally, test our example bindgen + build.rs integration template project.
+
+cd bindgen-integration
+cargo test --features "%BINDGEN_FEATURES%" || exit /b 1
+cargo test --release --features "%BINDGEN_FEATURES%" || exit /b 1
--- a/third_party/rust/bindgen/ci/test.sh
+++ b/third_party/rust/bindgen/ci/test.sh
@@ -1,31 +1,38 @@
 #!/usr/bin/env bash
 
 set -xeu
 cd "$(dirname "$0")/.."
 
 export RUST_BACKTRACE=1
 
+# Disallow system header file includes in our test suite.
+./ci/no-includes.sh
+
 # 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
 
 cargo test --release --features "$BINDGEN_FEATURES testing_only_extra_assertions"
 ./ci/assert-no-diff.sh
 
-# Now test the expectations' size and alignment tests.
+if [ -v "${TRAVIS_OS_NAME}" ]; then
+
+    # Now test the expectations' size and alignment tests.
 
-pushd tests/expectations
-cargo test
-cargo test --release
-popd
+    pushd tests/expectations
+    cargo test
+    cargo test --release
+    popd
 
-# And finally, test our example bindgen + build.rs integration template project.
+    # And finally, test our example bindgen + build.rs integration template project.
 
-cd bindgen-integration
-cargo test --features "$BINDGEN_FEATURES"
-cargo test --release --features "$BINDGEN_FEATURES"
+    cd bindgen-integration
+    cargo test --features "$BINDGEN_FEATURES"
+    cargo test --release --features "$BINDGEN_FEATURES"
+
+fi
--- a/third_party/rust/bindgen/src/codegen/helpers.rs
+++ b/third_party/rust/bindgen/src/codegen/helpers.rs
@@ -25,18 +25,18 @@ pub mod attributes {
     pub fn derives(which_ones: &[&str]) -> ast::Attribute {
         aster::AstBuilder::new().attr().list("derive").words(which_ones).build()
     }
 
     pub fn inline() -> ast::Attribute {
         aster::AstBuilder::new().attr().word("inline")
     }
 
-    pub fn doc(comment: &str) -> ast::Attribute {
-        aster::AstBuilder::new().attr().doc(comment)
+    pub fn doc(comment: String) -> ast::Attribute {
+        aster::AstBuilder::new().attr().doc(&*comment)
     }
 
     pub fn link_name(name: &str) -> ast::Attribute {
         aster::AstBuilder::new().attr().name_value("link_name").str(name)
     }
 }
 
 /// Generates a proper type for a field or type with a given `Layout`, that is,
--- a/third_party/rust/bindgen/src/codegen/mod.rs
+++ b/third_party/rust/bindgen/src/codegen/mod.rs
@@ -6,24 +6,24 @@ use self::helpers::{BlobTyBuilder, attri
 use self::struct_layout::StructLayoutTracker;
 
 use aster;
 use aster::struct_field::StructFieldBuilder;
 
 use ir::annotations::FieldAccessorKind;
 use ir::comp::{Base, BitfieldUnit, Bitfield, CompInfo, CompKind, Field,
                FieldData, FieldMethods, Method, MethodKind};
+use ir::comment;
 use ir::context::{BindgenContext, ItemId};
 use ir::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault};
 use ir::dot;
 use ir::enum_ty::{Enum, EnumVariant, EnumVariantValue};
 use ir::function::{Abi, Function, FunctionSig};
 use ir::int::IntKind;
-use ir::item::{Item, ItemAncestors, ItemCanonicalName, ItemCanonicalPath,
-               ItemSet};
+use ir::item::{IsOpaque, Item, ItemCanonicalName, ItemCanonicalPath};
 use ir::item_kind::ItemKind;
 use ir::layout::Layout;
 use ir::module::Module;
 use ir::objc::{ObjCInterface, ObjCMethod};
 use ir::template::{AsTemplateParam, TemplateInstantiation, TemplateParameters};
 use ir::ty::{Type, TypeKind};
 use ir::var::Var;
 
@@ -31,36 +31,29 @@ use std::borrow::Cow;
 use std::cell::Cell;
 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;
 use syntax::ast;
-use syntax::codemap::{Span, respan};
+use syntax::codemap::{DUMMY_SP, Span, respan};
 use syntax::ptr::P;
 
-fn root_import_depth(ctx: &BindgenContext, item: &Item) -> usize {
-    if !ctx.options().enable_cxx_namespaces {
-        return 0;
-    }
-
-    item.ancestors(ctx)
-        .filter(|id| ctx.resolve_item(*id).is_module())
-        .fold(1, |i, _| i + 1)
-}
+// Name of type defined in constified enum module
+pub static CONSTIFIED_ENUM_MODULE_REPR_NAME: &'static str = "Type";
 
 fn top_level_path(ctx: &BindgenContext, item: &Item) -> Vec<ast::Ident> {
     let mut path = vec![ctx.rust_ident_raw("self")];
 
     if ctx.options().enable_cxx_namespaces {
         let super_ = ctx.rust_ident_raw("super");
 
-        for _ in 0..root_import_depth(ctx, item) {
+        for _ in 0..item.codegen_depth(ctx) {
             path.push(super_.clone());
         }
     }
 
     path
 }
 
 fn root_import(ctx: &BindgenContext, module: &Item) -> P<ast::Item> {
@@ -239,17 +232,16 @@ impl ForeignModBuilder {
     fn with_foreign_items<I>(mut self, items: I) -> Self
         where I: IntoIterator<Item = ast::ForeignItem>,
     {
         self.inner.items.extend(items.into_iter());
         self
     }
 
     fn build(self, ctx: &BindgenContext) -> P<ast::Item> {
-        use syntax::codemap::DUMMY_SP;
         P(ast::Item {
             ident: ctx.rust_ident(""),
             id: ast::DUMMY_NODE_ID,
             node: ast::ItemKind::ForeignMod(self.inner),
             vis: ast::Visibility::Public,
             attrs: vec![],
             span: DUMMY_SP,
         })
@@ -285,85 +277,80 @@ impl ToPtr for P<ast::Ty> {
 
 trait CodeGenerator {
     /// Extra information from the caller.
     type Extra;
 
     fn codegen<'a>(&self,
                    ctx: &BindgenContext,
                    result: &mut CodegenResult<'a>,
-                   whitelisted_items: &ItemSet,
                    extra: &Self::Extra);
 }
 
 impl CodeGenerator for Item {
     type Extra = ();
 
     fn codegen<'a>(&self,
                    ctx: &BindgenContext,
                    result: &mut CodegenResult<'a>,
-                   whitelisted_items: &ItemSet,
                    _extra: &()) {
+        if !self.is_enabled_for_codegen(ctx) {
+            return;
+        }
+
         if self.is_hidden(ctx) || result.seen(self.id()) {
             debug!("<Item as CodeGenerator>::codegen: Ignoring hidden or seen: \
                    self = {:?}",
                    self);
             return;
         }
 
         debug!("<Item as CodeGenerator>::codegen: self = {:?}", self);
-        if !whitelisted_items.contains(&self.id()) {
+        if !ctx.codegen_items().contains(&self.id()) {
             // TODO(emilio, #453): Figure out what to do when this happens
             // legitimately, we could track the opaque stuff and disable the
             // assertion there I guess.
             error!("Found non-whitelisted item in code generation: {:?}", self);
         }
 
         result.set_seen(self.id());
 
         match *self.kind() {
             ItemKind::Module(ref module) => {
-                module.codegen(ctx, result, whitelisted_items, self);
+                module.codegen(ctx, result, self);
             }
             ItemKind::Function(ref fun) => {
-                if ctx.options().codegen_config.functions {
-                    fun.codegen(ctx, result, whitelisted_items, self);
-                }
+                fun.codegen(ctx, result, self);
             }
             ItemKind::Var(ref var) => {
-                if ctx.options().codegen_config.vars {
-                    var.codegen(ctx, result, whitelisted_items, self);
-                }
+                var.codegen(ctx, result, self);
             }
             ItemKind::Type(ref ty) => {
-                if ctx.options().codegen_config.types {
-                    ty.codegen(ctx, result, whitelisted_items, self);
-                }
+                ty.codegen(ctx, result, self);
             }
         }
     }
 }
 
 impl CodeGenerator for Module {
     type Extra = Item;
 
     fn codegen<'a>(&self,
                    ctx: &BindgenContext,
                    result: &mut CodegenResult<'a>,
-                   whitelisted_items: &ItemSet,
                    item: &Item) {
         debug!("<Module as CodeGenerator>::codegen: item = {:?}", item);
 
         let codegen_self = |result: &mut CodegenResult,
                             found_any: &mut bool| {
             for child in self.children() {
-                if whitelisted_items.contains(child) {
+                if ctx.codegen_items().contains(child) {
                     *found_any = true;
                     ctx.resolve_item(*child)
-                        .codegen(ctx, result, whitelisted_items, &());
+                        .codegen(ctx, result, &());
                 }
             }
 
             if item.id() == ctx.root_module() {
                 if result.saw_union && !ctx.options().unstable_rust {
                     utils::prepend_union_types(ctx, &mut *result);
                 }
                 if result.saw_incomplete_array {
@@ -418,28 +405,38 @@ impl CodeGenerator for Module {
     }
 }
 
 impl CodeGenerator for Var {
     type Extra = Item;
     fn codegen<'a>(&self,
                    ctx: &BindgenContext,
                    result: &mut CodegenResult<'a>,
-                   _whitelisted_items: &ItemSet,
                    item: &Item) {
         use ir::var::VarType;
         debug!("<Var as CodeGenerator>::codegen: item = {:?}", item);
+        debug_assert!(item.is_enabled_for_codegen(ctx));
 
         let canonical_name = item.canonical_name(ctx);
 
         if result.seen_var(&canonical_name) {
             return;
         }
         result.saw_var(&canonical_name);
 
+        // We can't generate bindings to static variables of templates. The
+        // number of actual variables for a single declaration are open ended
+        // and we don't know what instantiations do or don't exist.
+        let type_params = item.all_template_params(ctx);
+        if let Some(params) = type_params {
+            if !params.is_empty() {
+                return;
+            }
+        }
+
         let ty = self.ty().to_rust_ty_or_opaque(ctx, &());
 
         if let Some(val) = self.val() {
             let const_item = aster::AstBuilder::new()
                 .item()
                 .pub_()
                 .const_(canonical_name)
                 .expr();
@@ -512,19 +509,19 @@ impl CodeGenerator for Var {
 }
 
 impl CodeGenerator for Type {
     type Extra = Item;
 
     fn codegen<'a>(&self,
                    ctx: &BindgenContext,
                    result: &mut CodegenResult<'a>,
-                   whitelisted_items: &ItemSet,
                    item: &Item) {
         debug!("<Type as CodeGenerator>::codegen: item = {:?}", item);
+        debug_assert!(item.is_enabled_for_codegen(ctx));
 
         match *self.kind() {
             TypeKind::Void |
             TypeKind::NullPtr |
             TypeKind::Int(..) |
             TypeKind::Float(..) |
             TypeKind::Complex(..) |
             TypeKind::Array(..) |
@@ -535,20 +532,20 @@ impl CodeGenerator for Type {
             TypeKind::ResolvedTypeRef(..) |
             TypeKind::Opaque |
             TypeKind::Named => {
                 // These items don't need code generation, they only need to be
                 // converted to rust types in fields, arguments, and such.
                 return;
             }
             TypeKind::TemplateInstantiation(ref inst) => {
-                inst.codegen(ctx, result, whitelisted_items, item)
+                inst.codegen(ctx, result, item)
             }
             TypeKind::Comp(ref ci) => {
-                ci.codegen(ctx, result, whitelisted_items, item)
+                ci.codegen(ctx, result, item)
             }
             TypeKind::TemplateAlias(inner, _) |
             TypeKind::Alias(inner) => {
                 let inner_item = ctx.resolve_item(inner);
                 let name = item.canonical_name(ctx);
 
                 // Try to catch the common pattern:
                 //
@@ -563,17 +560,17 @@ impl CodeGenerator for Type {
                 // If this is a known named type, disallow generating anything
                 // for it too.
                 let spelling = self.name().expect("Unnamed alias?");
                 if utils::type_from_named(ctx, spelling, inner).is_some() {
                     return;
                 }
 
                 let mut used_template_params = item.used_template_params(ctx);
-                let inner_rust_type = if item.is_opaque(ctx) {
+                let inner_rust_type = if item.is_opaque(ctx, &()) {
                     used_template_params = None;
                     self.to_opaque(ctx, item)
                 } else {
                     // Its possible that we have better layout information than
                     // the inner type does, so fall back to an opaque blob based
                     // on our layout if converting the inner item fails.
                     inner_item.try_to_rust_ty_or_opaque(ctx, &())
                         .unwrap_or_else(|_| self.to_opaque(ctx, item))
@@ -599,20 +596,18 @@ impl CodeGenerator for Type {
                               inner_item);
                         return;
                     }
                 }
 
                 let rust_name = ctx.rust_ident(&name);
                 let mut typedef = aster::AstBuilder::new().item().pub_();
 
-                if ctx.options().generate_comments {
-                    if let Some(comment) = item.comment() {
-                        typedef = typedef.attr().doc(comment);
-                    }
+                if let Some(comment) = item.comment(ctx) {
+                    typedef = typedef.with_attr(attributes::doc(comment));
                 }
 
                 // We prefer using `pub use` over `pub type` because of:
                 // https://github.com/rust-lang/rust/issues/26264
                 let simple_enum_path = match inner_rust_type.node {
                     ast::TyKind::Path(None, ref p) => {
                         if used_template_params.is_none() &&
                            inner_item.expect_type()
@@ -655,23 +650,23 @@ impl CodeGenerator for Type {
                             }
                         }
                     }
                     generics.build().build_ty(inner_rust_type)
                 };
                 result.push(typedef)
             }
             TypeKind::Enum(ref ei) => {
-                ei.codegen(ctx, result, whitelisted_items, item)
+                ei.codegen(ctx, result, item)
             }
             TypeKind::ObjCId | TypeKind::ObjCSel => {
                 result.saw_objc();
             }
             TypeKind::ObjCInterface(ref interface) => {
-                interface.codegen(ctx, result, whitelisted_items, item)
+                interface.codegen(ctx, result, item)
             }
             ref u @ TypeKind::UnresolvedTypeRef(..) => {
                 unreachable!("Should have been resolved after parsing {:?}!", u)
             }
         }
     }
 }
 
@@ -697,19 +692,20 @@ impl<'a> Vtable<'a> {
 }
 
 impl<'a> CodeGenerator for Vtable<'a> {
     type Extra = Item;
 
     fn codegen<'b>(&self,
                    ctx: &BindgenContext,
                    result: &mut CodegenResult<'b>,
-                   _whitelisted_items: &ItemSet,
                    item: &Item) {
         assert_eq!(item.id(), self.item_id);
+        debug_assert!(item.is_enabled_for_codegen(ctx));
+
         // For now, generate an empty struct, later we should generate function
         // pointers and whatnot.
         let attributes = vec![attributes::repr("C")];
 
         let vtable = aster::AstBuilder::new()
             .item()
             .pub_()
             .with_attrs(attributes)
@@ -738,34 +734,48 @@ impl<'a> TryToRustTy for Vtable<'a> {
 }
 
 impl CodeGenerator for TemplateInstantiation {
     type Extra = Item;
 
     fn codegen<'a>(&self,
                    ctx: &BindgenContext,
                    result: &mut CodegenResult<'a>,
-                   _whitelisted_items: &ItemSet,
                    item: &Item) {
+        debug_assert!(item.is_enabled_for_codegen(ctx));
+
         // 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 {
+        // opportunity to generate tests for their layout here. If the
+        // instantiation is opaque, then its presumably because we don't
+        // properly understand it (maybe because of specializations), and so we
+        // shouldn't emit layout tests either.
+        if !ctx.options().layout_tests || self.is_opaque(ctx, item) {
             return
         }
 
+        // If there are any unbound type parameters, then we can't generate a
+        // layout test because we aren't dealing with a concrete type with a
+        // concrete size and alignment.
+        if ctx.uses_any_template_parameters(item.id()) {
+            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 name = item.full_disambiguated_name(ctx);
+            let mut fn_name = format!("__bindgen_test_layout_{}_instantiation", name);
+            let times_seen = result.overload_number(&fn_name);
+            if times_seen > 0 {
+                write!(&mut fn_name, "_{}", times_seen).unwrap();
+            }
 
             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(),
@@ -809,16 +819,17 @@ impl Iterator for AnonFieldNames {
 
 /// 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,
+                     codegen_depth: usize,
                      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)
@@ -827,43 +838,46 @@ trait FieldCodegen<'a> {
 }
 
 impl<'a> FieldCodegen<'a> for Field {
     type Extra = ();
 
     fn codegen<F, M>(&self,
                      ctx: &BindgenContext,
                      fields_should_be_private: bool,
+                     codegen_depth: usize,
                      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,
+                             codegen_depth,
                              accessor_kind,
                              parent,
                              anon_field_names,
                              result,
                              struct_layout,
                              fields,
                              methods,
                              ());
             }
             Field::Bitfields(ref unit) => {
                 unit.codegen(ctx,
                              fields_should_be_private,
+                             codegen_depth,
                              accessor_kind,
                              parent,
                              anon_field_names,
                              result,
                              struct_layout,
                              fields,
                              methods,
                              ());
@@ -873,16 +887,17 @@ impl<'a> FieldCodegen<'a> for Field {
 }
 
 impl<'a> FieldCodegen<'a> for FieldData {
     type Extra = ();
 
     fn codegen<F, M>(&self,
                      ctx: &BindgenContext,
                      fields_should_be_private: bool,
+                     codegen_depth: usize,
                      accessor_kind: FieldAccessorKind,
                      parent: &CompInfo,
                      anon_field_names: &mut AnonFieldNames,
                      result: &mut CodegenResult,
                      struct_layout: &mut StructLayoutTracker,
                      fields: &mut F,
                      methods: &mut M,
                      _: ())
@@ -915,18 +930,19 @@ impl<'a> FieldCodegen<'a> for FieldData 
                 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));
+            if let Some(raw_comment) = self.comment() {
+                let comment = comment::preprocess(raw_comment, codegen_depth + 1);
+                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() {
@@ -1123,16 +1139,17 @@ impl Bitfield {
 }
 
 impl<'a> FieldCodegen<'a> for BitfieldUnit {
     type Extra = ();
 
     fn codegen<F, M>(&self,
                      ctx: &BindgenContext,
                      fields_should_be_private: bool,
+                     codegen_depth: usize,
                      accessor_kind: FieldAccessorKind,
                      parent: &CompInfo,
                      anon_field_names: &mut AnonFieldNames,
                      result: &mut CodegenResult,
                      struct_layout: &mut StructLayoutTracker,
                      fields: &mut F,
                      methods: &mut M,
                      _: ())
@@ -1167,16 +1184,17 @@ impl<'a> FieldCodegen<'a> for BitfieldUn
         };
 
         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,
+                       codegen_depth,
                        accessor_kind,
                        parent,
                        anon_field_names,
                        result,
                        struct_layout,
                        fields,
                        methods,
                        (&unit_field_name, unit_field_int_ty.clone()));
@@ -1247,16 +1265,17 @@ fn bitfield_setter_name(ctx: &BindgenCon
 }
 
 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,
+                     _codegen_depth: usize,
                      _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,
@@ -1346,19 +1365,19 @@ impl<'a> FieldCodegen<'a> for Bitfield {
 }
 
 impl CodeGenerator for CompInfo {
     type Extra = Item;
 
     fn codegen<'a>(&self,
                    ctx: &BindgenContext,
                    result: &mut CodegenResult<'a>,
-                   whitelisted_items: &ItemSet,
                    item: &Item) {
         debug!("<CompInfo as CodeGenerator>::codegen: item = {:?}", item);
+        debug_assert!(item.is_enabled_for_codegen(ctx));
 
         // 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;
         }
 
         let used_template_params = item.used_template_params(ctx);
@@ -1379,30 +1398,28 @@ impl CodeGenerator for CompInfo {
                 .unwrap();
             result.push(tuple_struct);
             return;
         }
 
         let mut attributes = vec![];
         let mut needs_clone_impl = false;
         let mut needs_default_impl = false;
-        if ctx.options().generate_comments {
-            if let Some(comment) = item.comment() {
-                attributes.push(attributes::doc(comment));
-            }
+        if let Some(comment) = item.comment(ctx) {
+            attributes.push(attributes::doc(comment));
         }
         if self.packed() {
             attributes.push(attributes::repr_list(&["C", "packed"]));
         } else {
             attributes.push(attributes::repr("C"));
         }
 
         let is_union = self.kind() == CompKind::Union;
         let mut derives = vec![];
-        if item.can_derive_debug(ctx, ()) {
+        if item.can_derive_debug(ctx) {
             derives.push("Debug");
         }
 
         if item.can_derive_default(ctx, ()) {
             derives.push("Default");
         } else {
             needs_default_impl = ctx.options().derive_default;
         }
@@ -1451,20 +1468,20 @@ 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, &canonical_name);
-        if self.needs_explicit_vtable(ctx) {
+        if self.needs_explicit_vtable(ctx, item) {
             let vtable =
                 Vtable::new(item.id(), self.methods(), self.base_members());
-            vtable.codegen(ctx, result, whitelisted_items, item);
+            vtable.codegen(ctx, result, item);
 
             let vtable_type = vtable.try_to_rust_ty(ctx, &())
                 .expect("vtable to Rust type conversion is infallible")
                 .to_ptr(true, ctx.span());
 
             let vtable_field = StructFieldBuilder::named("vtable_")
                 .pub_()
                 .build_ty(vtable_type);
@@ -1482,17 +1499,17 @@ impl CodeGenerator for CompInfo {
             if base.is_virtual() {
                 continue;
             }
 
             let base_ty = ctx.resolve_type(base.ty);
             // NB: We won't include unsized types in our base chain because they
             // would contribute to our size given the dummy field we insert for
             // unsized types.
-            if base_ty.is_unsized(ctx) {
+            if base_ty.is_unsized(ctx, &base.ty) {
                 continue;
             }
 
             let inner = base.ty.to_rust_ty_or_opaque(ctx, &());
             let field_name = if i == 0 {
                 "_base".into()
             } else {
                 format!("_base_{}", i)
@@ -1515,19 +1532,21 @@ impl CodeGenerator for CompInfo {
             .private_fields()
             .unwrap_or(false);
         let struct_accessor_kind = item.annotations()
             .accessor_kind()
             .unwrap_or(FieldAccessorKind::None);
 
         let mut methods = vec![];
         let mut anon_field_names = AnonFieldNames::default();
+        let codegen_depth = item.codegen_depth(ctx);
         for field in self.fields() {
             field.codegen(ctx,
                           fields_should_be_private,
+                          codegen_depth,
                           struct_accessor_kind,
                           self,
                           &mut anon_field_names,
                           result,
                           &mut struct_layout,
                           &mut fields,
                           &mut methods,
                           ());
@@ -1541,34 +1560,35 @@ impl CodeGenerator for CompInfo {
                 .build_ty(ty);
 
             struct_layout.saw_union(layout);
 
             fields.push(field);
         }
 
         // Yeah, sorry about that.
-        if item.is_opaque(ctx) {
+        let is_opaque = item.is_opaque(ctx, &());
+        if is_opaque {
             fields.clear();
             methods.clear();
 
             match layout {
                 Some(l) => {
                     let ty = BlobTyBuilder::new(l).build();
                     let field =
                         StructFieldBuilder::named("_bindgen_opaque_blob")
                             .pub_()
                             .build_ty(ty);
                     fields.push(field);
                 }
                 None => {
                     warn!("Opaque type without layout! Expect dragons!");
                 }
             }
-        } else if !is_union && !self.is_unsized(ctx) {
+        } else if !is_union && !self.is_unsized(ctx, &item.id()) {
             if let Some(padding_field) =
                 layout.and_then(|layout| {
                     struct_layout.pad_struct(layout)
                 }) {
                 fields.push(padding_field);
             }
 
             if let Some(align_field) =
@@ -1576,24 +1596,31 @@ impl CodeGenerator for CompInfo {
                 fields.push(align_field);
             }
         }
 
         // C++ requires every struct to be addressable, so what C++ compilers do
         // is making the struct 1-byte sized.
         //
         // This is apparently not the case for C, see:
-        // https://github.com/servo/rust-bindgen/issues/551
+        // https://github.com/rust-lang-nursery/rust-bindgen/issues/551
         //
         // Just get the layout, and assume C++ if not.
         //
         // NOTE: This check is conveniently here to avoid the dummy fields we
         // may add for unused template parameters.
-        if self.is_unsized(ctx) {
-            let has_address = layout.map_or(true, |l| l.size != 0);
+        if self.is_unsized(ctx, &item.id()) {
+            let has_address = if is_opaque {
+                // Generate the address field if it's an opaque type and
+                // couldn't determine the layout of the blob.
+                layout.is_none()
+            } else {
+                layout.map_or(true, |l| l.size != 0)
+            };
+
             if has_address {
                 let ty = BlobTyBuilder::new(Layout::new(1, 1)).build();
                 let field = StructFieldBuilder::named("_address")
                     .pub_()
                     .build_ty(ty);
                 fields.push(field);
             }
         }
@@ -1628,31 +1655,33 @@ impl CodeGenerator for CompInfo {
 
         // Generate the inner types and all that stuff.
         //
         // TODO: In the future we might want to be smart, and use nested
         // modules, and whatnot.
         for ty in self.inner_types() {
             let child_item = ctx.resolve_item(*ty);
             // assert_eq!(child_item.parent_id(), item.id());
-            child_item.codegen(ctx, result, whitelisted_items, &());
+            child_item.codegen(ctx, result, &());
         }
 
         // NOTE: Some unexposed attributes (like alignment attributes) may
         // affect layout, so we're bad and pray to the gods for avoid sending
         // all the tests to shit when parsing things like max_align_t.
         if self.found_unknown_attr() {
             warn!("Type {} has an unkown attribute that may affect layout",
                   canonical_name);
         }
 
         if used_template_params.is_none() {
-            for var in self.inner_vars() {
-                ctx.resolve_item(*var)
-                    .codegen(ctx, result, whitelisted_items, &());
+            if !is_opaque {
+                for var in self.inner_vars() {
+                    ctx.resolve_item(*var)
+                        .codegen(ctx, result, &());
+                }
             }
 
             if ctx.options().layout_tests {
                 if let Some(layout) = layout {
                     let fn_name = format!("bindgen_test_layout_{}", canonical_name);
                     let fn_name = ctx.rust_ident_raw(&fn_name);
                     let type_name = ctx.rust_ident_raw(&canonical_name);
                     let prefix = ctx.trait_prefix();
@@ -1669,26 +1698,26 @@ impl CodeGenerator for CompInfo {
                     } else {
                         quote_item!(ctx.ext_cx(),
                             assert_eq!($align_of_expr,
                                        $align,
                                        concat!("Alignment of ", stringify!($type_name)));
                         )
                     };
 
-                    // FIXME when [issue #465](https://github.com/servo/rust-bindgen/issues/465) ready
+                    // FIXME when [issue #465](https://github.com/rust-lang-nursery/rust-bindgen/issues/465) ready
                     let too_many_base_vtables = self.base_members()
                         .iter()
                         .filter(|base| {
-                            ctx.resolve_type(base.ty).has_vtable(ctx)
+                            ctx.lookup_item_id_has_vtable(&base.ty)
                         })
                         .count() > 1;
 
-                    let should_skip_field_offset_checks = item.is_opaque(ctx) ||
-                                                          too_many_base_vtables;
+                    let should_skip_field_offset_checks =
+                        is_opaque || too_many_base_vtables;
 
                     let check_field_offset = if should_skip_field_offset_checks {
                         None
                     } else {
                         let asserts = self.fields()
                         .iter()
                         .filter_map(|field| match *field {
                             Field::DataMember(ref f) if f.name().is_some() => Some(f),
@@ -1730,32 +1759,30 @@ impl CodeGenerator for CompInfo {
             let mut method_names = Default::default();
             if ctx.options().codegen_config.methods {
                 for method in self.methods() {
                     assert!(method.kind() != MethodKind::Constructor);
                     method.codegen_method(ctx,
                                           &mut methods,
                                           &mut method_names,
                                           result,
-                                          whitelisted_items,
                                           self);
                 }
             }
 
             if ctx.options().codegen_config.constructors {
                 for sig in self.constructors() {
                     Method::new(MethodKind::Constructor,
                                 *sig,
                                 /* const */
                                 false)
                         .codegen_method(ctx,
                                         &mut methods,
                                         &mut method_names,
                                         result,
-                                        whitelisted_items,
                                         self);
                 }
             }
 
             if ctx.options().codegen_config.destructors {
                 if let Some((is_virtual, destructor)) = self.destructor() {
                     let kind = if is_virtual {
                         MethodKind::VirtualDestructor
@@ -1763,17 +1790,16 @@ impl CodeGenerator for CompInfo {
                         MethodKind::Destructor
                     };
 
                     Method::new(kind, destructor, false)
                         .codegen_method(ctx,
                                         &mut methods,
                                         &mut method_names,
                                         result,
-                                        whitelisted_items,
                                         self);
                 }
             }
         }
 
         // NB: We can't use to_rust_ty here since for opaque types this tries to
         // use the specialization knowledge to generate a blob field.
         let ty_for_impl = aster::AstBuilder::new()
@@ -1848,35 +1874,45 @@ impl CodeGenerator for CompInfo {
 }
 
 trait MethodCodegen {
     fn codegen_method<'a>(&self,
                           ctx: &BindgenContext,
                           methods: &mut Vec<ast::ImplItem>,
                           method_names: &mut HashMap<String, usize>,
                           result: &mut CodegenResult<'a>,
-                          whitelisted_items: &ItemSet,
                           parent: &CompInfo);
 }
 
 impl MethodCodegen for Method {
     fn codegen_method<'a>(&self,
                           ctx: &BindgenContext,
                           methods: &mut Vec<ast::ImplItem>,
                           method_names: &mut HashMap<String, usize>,
                           result: &mut CodegenResult<'a>,
-                          whitelisted_items: &ItemSet,
                           _parent: &CompInfo) {
+        assert!({
+            let cc = &ctx.options().codegen_config;
+            match self.kind() {
+                MethodKind::Constructor => cc.constructors,
+                MethodKind::Destructor => cc.destructors,
+                MethodKind::VirtualDestructor => cc.destructors,
+                MethodKind::Static |
+                MethodKind::Normal |
+                MethodKind::Virtual => cc.methods,
+            }
+        });
+
         if self.is_virtual() {
             return; // FIXME
         }
 
         // First of all, output the actual function.
         let function_item = ctx.resolve_item(self.signature());
-        function_item.codegen(ctx, result, whitelisted_items, &());
+        function_item.codegen(ctx, result, &());
 
         let function = function_item.expect_function();
         let signature_item = ctx.resolve_item(function.signature());
         let mut name = match self.kind() {
             MethodKind::Constructor => "new".into(),
             MethodKind::Destructor => "destruct".into(),
             _ => function.name().to_owned(),
         };
@@ -2024,39 +2060,56 @@ impl MethodCodegen for Method {
 /// A helper type to construct enums, either bitfield ones or rust-style ones.
 enum EnumBuilder<'a> {
     Rust(aster::item::ItemEnumBuilder<aster::invoke::Identity>),
     Bitfield {
         canonical_name: &'a str,
         aster: P<ast::Item>,
     },
     Consts { aster: P<ast::Item> },
+    ModuleConsts {
+        module_name: &'a str,
+        module_items: Vec<P<ast::Item>>,
+    },
 }
 
 impl<'a> EnumBuilder<'a> {
     /// Create a new enum given an item builder, a canonical name, a name for
     /// the representation, and whether it should be represented as a rust enum.
     fn new(aster: aster::item::ItemBuilder<aster::invoke::Identity>,
            name: &'a str,
            repr: P<ast::Ty>,
            bitfield_like: bool,
-           constify: bool)
+           constify: bool,
+           constify_module: bool)
            -> Self {
         if bitfield_like {
             EnumBuilder::Bitfield {
                 canonical_name: name,
                 aster: aster.tuple_struct(name)
                     .field()
                     .pub_()
                     .build_ty(repr)
                     .build(),
             }
         } else if constify {
-            EnumBuilder::Consts {
-                aster: aster.type_(name).build_ty(repr),
+            if constify_module {
+                let type_definition = aster::item::ItemBuilder::new()
+                    .pub_()
+                    .type_(CONSTIFIED_ENUM_MODULE_REPR_NAME)
+                    .build_ty(repr);
+
+                EnumBuilder::ModuleConsts {
+                    module_name: name,
+                    module_items: vec![type_definition],
+                }
+            } else  {
+                EnumBuilder::Consts {
+                    aster: aster.type_(name).build_ty(repr),
+                }
             }
         } else {
             EnumBuilder::Rust(aster.enum_(name))
         }
     }
 
     /// Add a variant to this enum.
     fn with_variant<'b>(self,
@@ -2118,16 +2171,37 @@ impl<'a> EnumBuilder<'a> {
                     .const_(&*constant_name)
                     .expr()
                     .build(expr)
                     .build(rust_ty);
 
                 result.push(constant);
                 self
             }
+            EnumBuilder::ModuleConsts { module_name, module_items, .. } => {
+                // Variant type
+                let inside_module_type =
+                    aster::AstBuilder::new().ty().id(CONSTIFIED_ENUM_MODULE_REPR_NAME);
+
+                let constant = aster::AstBuilder::new()
+                    .item()
+                    .pub_()
+                    .const_(&*variant_name)
+                    .expr()
+                    .build(expr)
+                    .build(inside_module_type.clone());
+
+                let mut module_items = module_items.clone();
+                module_items.push(constant);
+
+                EnumBuilder::ModuleConsts {
+                    module_name,
+                    module_items,
+                }
+            }
         }
     }
 
     fn build<'b>(self,
                  ctx: &BindgenContext,
                  rust_ty: P<ast::Ty>,
                  result: &mut CodegenResult<'b>)
                  -> P<ast::Item> {
@@ -2183,29 +2257,45 @@ impl<'a> EnumBuilder<'a> {
                     }
                 )
                     .unwrap();
                 result.push(impl_);
 
                 aster
             }
             EnumBuilder::Consts { aster, .. } => aster,
+            EnumBuilder::ModuleConsts { module_items, module_name, .. } => {
+                // Create module item with type and variant definitions
+                let module_item = P(ast::Item {
+                    ident: ast::Ident::from_str(module_name),
+                    attrs: vec![],
+                    id: ast::DUMMY_NODE_ID,
+                    node: ast::ItemKind::Mod(ast::Mod {
+                        inner: DUMMY_SP,
+                        items: module_items,
+                    }),
+                    vis: ast::Visibility::Public,
+                    span: DUMMY_SP,
+                });
+
+                module_item
+            }
         }
     }
 }
 
 impl CodeGenerator for Enum {
     type Extra = Item;
 
     fn codegen<'a>(&self,
                    ctx: &BindgenContext,
                    result: &mut CodegenResult<'a>,
-                   _whitelisted_items: &ItemSet,
                    item: &Item) {
         debug!("<Enum as CodeGenerator>::codegen: item = {:?}", item);
+        debug_assert!(item.is_enabled_for_codegen(ctx));
 
         let name = item.canonical_name(ctx);
         let enum_ty = item.expect_type();
         let layout = enum_ty.layout(ctx);
 
         let repr = self.repr().map(|repr| ctx.resolve_type(repr));
         let repr = match repr {
             Some(repr) => {
@@ -2248,17 +2338,20 @@ impl CodeGenerator for Enum {
         let is_bitfield = {
             ctx.options().bitfield_enums.matches(&name) ||
             (enum_ty.name().is_none() &&
              self.variants()
                 .iter()
                 .any(|v| ctx.options().bitfield_enums.matches(&v.name())))
         };
 
-        let is_constified_enum = {
+        let is_constified_enum_module = self.is_constified_enum_module(ctx, item);
+
+        let is_constified_enum =  {
+            is_constified_enum_module ||
             ctx.options().constified_enums.matches(&name) ||
             (enum_ty.name().is_none() &&
              self.variants()
                 .iter()
                 .any(|v| ctx.options().constified_enums.matches(&v.name())))
         };
 
         let is_rust_enum = !is_bitfield && !is_constified_enum;
@@ -2270,20 +2363,18 @@ impl CodeGenerator for Enum {
         if is_rust_enum {
             if !self.variants().is_empty() {
                 builder = builder.with_attr(attributes::repr(repr_name));
             }
         } else if is_bitfield {
             builder = builder.with_attr(attributes::repr("C"));
         }
 
-        if ctx.options().generate_comments {
-            if let Some(comment) = item.comment() {
-                builder = builder.with_attr(attributes::doc(comment));
-            }
+        if let Some(comment) = item.comment(ctx) {
+            builder = builder.with_attr(attributes::doc(comment));
         }
 
         if !is_constified_enum {
             let derives = attributes::derives(&["Debug",
                                                 "Copy",
                                                 "Clone",
                                                 "PartialEq",
                                                 "Eq",
@@ -2328,17 +2419,18 @@ impl CodeGenerator for Enum {
         let repr = self.repr()
             .and_then(|repr| repr.try_to_rust_ty_or_opaque(ctx, &()).ok())
             .unwrap_or_else(|| helpers::ast_ty::raw_type(ctx, repr_name));
 
         let mut builder = EnumBuilder::new(builder,
                                            &name,
                                            repr,
                                            is_bitfield,
-                                           is_constified_enum);
+                                           is_constified_enum,
+                                           is_constified_enum_module);
 
         // A map where we keep a value -> variant relation.
         let mut seen_values = HashMap::<_, String>::new();
         let enum_rust_ty = item.to_rust_ty_or_opaque(ctx, &());
         let is_toplevel = item.is_toplevel(ctx);
 
         // Used to mangle the constants we generate in the unnamed-enum case.
         let parent_canonical_name = if is_toplevel {
@@ -2731,42 +2823,42 @@ impl TryToRustTy for Type {
                 let path = item.namespace_aware_canonical_path(ctx);
                 Ok(aster::AstBuilder::new()
                     .ty()
                     .path()
                     .ids(path)
                     .build())
             }
             TypeKind::TemplateInstantiation(ref inst) => {
-                inst.try_to_rust_ty(ctx, self)
+                inst.try_to_rust_ty(ctx, item)
             }
             TypeKind::ResolvedTypeRef(inner) => inner.try_to_rust_ty(ctx, &()),
             TypeKind::TemplateAlias(inner, _) |
             TypeKind::Alias(inner) => {
                 let template_params = item.used_template_params(ctx)
                     .unwrap_or(vec![])
                     .into_iter()
                     .filter(|param| param.is_template_param(ctx, &()))
                     .collect::<Vec<_>>();
 
                 let spelling = self.name().expect("Unnamed alias?");
-                if item.is_opaque(ctx) && !template_params.is_empty() {
+                if item.is_opaque(ctx, &()) && !template_params.is_empty() {
                     self.try_to_opaque(ctx, item)
                 } else if let Some(ty) = utils::type_from_named(ctx,
                                                                 spelling,
                                                                 inner) {
                     Ok(ty)
                 } else {
                     utils::build_templated_path(item, ctx, template_params)
                 }
             }
             TypeKind::Comp(ref info) => {
                 let template_params = item.used_template_params(ctx);
                 if info.has_non_type_template_params() ||
-                   (item.is_opaque(ctx) && template_params.is_some()) {
+                   (item.is_opaque(ctx, &()) && template_params.is_some()) {
                     return self.try_to_opaque(ctx, item);
                 }
 
                 let template_params = template_params.unwrap_or(vec![]);
                 utils::build_templated_path(item,
                                             ctx,
                                             template_params)
             }
@@ -2810,46 +2902,50 @@ impl TryToRustTy for Type {
             ref u @ TypeKind::UnresolvedTypeRef(..) => {
                 unreachable!("Should have been resolved after parsing {:?}!", u)
             }
         }
     }
 }
 
 impl TryToOpaque for TemplateInstantiation {
-    type Extra = Type;
+    type Extra = Item;
 
     fn try_get_layout(&self,
                       ctx: &BindgenContext,
-                      self_ty: &Type)
+                      item: &Item)
                       -> error::Result<Layout> {
-        self_ty.layout(ctx).ok_or(error::Error::NoLayoutForOpaqueBlob)
+        item.expect_type().layout(ctx).ok_or(error::Error::NoLayoutForOpaqueBlob)
     }
 }
 
 impl TryToRustTy for TemplateInstantiation {
-    type Extra = Type;
+    type Extra = Item;
 
     fn try_to_rust_ty(&self,
                       ctx: &BindgenContext,
-                      _: &Type)
+                      item: &Item)
                       -> error::Result<P<ast::Ty>> {
+        if self.is_opaque(ctx, item) {
+            return Err(error::Error::InstantiationOfOpaqueType);
+        }
+
         let decl = self.template_definition();
         let mut ty = decl.try_to_rust_ty(ctx, &())?.unwrap();
 
         let decl_params = match decl.self_template_params(ctx) {
             Some(params) => params,
             None => {
                 // This can happen if we generated an opaque type for a partial
                 // template specialization, and we've hit an instantiation of
                 // that partial specialization.
                 extra_assert!(decl.into_resolver()
                                   .through_type_refs()
                                   .resolve(ctx)
-                                  .is_opaque(ctx));
+                                  .is_opaque(ctx, &()));
                 return Err(error::Error::InstantiationOfOpaqueType);
             }
         };
 
         // TODO: If the decl type is a template class/struct
         // declaration's member template declaration, it could rely on
         // generic template parameters from its outer template
         // class/struct. When we emit bindings for it, it could require
@@ -2926,19 +3022,30 @@ impl TryToRustTy for FunctionSig {
 }
 
 impl CodeGenerator for Function {
     type Extra = Item;
 
     fn codegen<'a>(&self,
                    ctx: &BindgenContext,
                    result: &mut CodegenResult<'a>,
-                   _whitelisted_items: &ItemSet,
                    item: &Item) {
         debug!("<Function as CodeGenerator>::codegen: item = {:?}", item);
+        debug_assert!(item.is_enabled_for_codegen(ctx));
+
+        // Similar to static member variables in a class template, we can't
+        // generate bindings to template functions, because the set of
+        // instantiations is open ended and we have no way of knowing which
+        // monomorphizations actually exist.
+        let type_params = item.all_template_params(ctx);
+        if let Some(params) = type_params {
+            if !params.is_empty() {
+                return;
+            }
+        }
 
         let name = self.name();
         let mut canonical_name = item.canonical_name(ctx);
         let mangled_name = self.mangled_name();
 
         {
             let seen_symbol_name = mangled_name.unwrap_or(&canonical_name);
 
@@ -2956,20 +3063,18 @@ impl CodeGenerator for Function {
             TypeKind::Function(ref sig) => sig,
             _ => panic!("Signature kind is not a Function: {:?}", signature),
         };
 
         let fndecl = utils::rust_fndecl_from_signature(ctx, signature_item);
 
         let mut attributes = vec![];
 
-        if ctx.options().generate_comments {
-            if let Some(comment) = item.comment() {
-                attributes.push(attributes::doc(comment));
-            }
+        if let Some(comment) = item.comment(ctx) {
+            attributes.push(attributes::doc(comment));
         }
 
         if let Some(mangled) = mangled_name {
             attributes.push(attributes::link_name(mangled));
         } else if name != canonical_name {
             attributes.push(attributes::link_name(name));
         }
 
@@ -3095,18 +3200,19 @@ fn objc_method_codegen(ctx: &BindgenCont
 }
 
 impl CodeGenerator for ObjCInterface {
     type Extra = Item;
 
     fn codegen<'a>(&self,
                    ctx: &BindgenContext,
                    result: &mut CodegenResult<'a>,
-                   _whitelisted_items: &ItemSet,
-                   _: &Item) {
+                   item: &Item) {
+        debug_assert!(item.is_enabled_for_codegen(ctx));
+
         let mut impl_items = vec![];
         let mut trait_items = vec![];
 
         for method in self.methods() {
             let (impl_item, trait_item) =
                 objc_method_codegen(ctx, method, None, "");
             impl_items.push(impl_item);
             trait_items.push(trait_item)
@@ -3148,43 +3254,40 @@ impl CodeGenerator for ObjCInterface {
             .build_ty(ty_for_impl);
 
         result.push(trait_block);
         result.push(impl_block);
         result.saw_objc();
     }
 }
 
-
-
 pub fn codegen(context: &mut BindgenContext) -> Vec<P<ast::Item>> {
     context.gen(|context| {
         let counter = Cell::new(0);
         let mut result = CodegenResult::new(&counter);
 
         debug!("codegen: {:?}", context.options());
 
-        let whitelisted_items: ItemSet = context.whitelisted_items().collect();
-
+        let codegen_items = context.codegen_items();
         if context.options().emit_ir {
-            for &id in whitelisted_items.iter() {
+            for &id in codegen_items {
                 let item = context.resolve_item(id);
                 println!("ir: {:?} = {:#?}", id, item);
             }
         }
 
         if let Some(path) = context.options().emit_ir_graphviz.as_ref() {
             match dot::write_dot_file(context, path) {
                 Ok(()) => info!("Your dot file was generated successfully into: {}", path),
                 Err(e) => error!("{}", e),
             }
         }
 
         context.resolve_item(context.root_module())
-            .codegen(context, &mut result, &whitelisted_items, &());
+            .codegen(context, &mut result, &());
 
         result.items
     })
 }
 
 mod utils {
     use super::{error, TryToRustTy, ToRustTyOrOpaque};
     use aster;
new file mode 100644
--- /dev/null
+++ b/third_party/rust/bindgen/src/ir/analysis/derive_debug.rs
@@ -0,0 +1,322 @@
+//! Determining which types for which we can emit `#[derive(Debug)]`.
+
+use super::{ConstrainResult, MonotoneFramework, generate_dependencies};
+use std::collections::HashSet;
+use std::collections::HashMap;
+use ir::context::{BindgenContext, ItemId};
+use ir::item::IsOpaque;
+use ir::traversal::EdgeKind;
+use ir::ty::RUST_DERIVE_IN_ARRAY_LIMIT;
+use ir::ty::TypeKind;
+use ir::comp::Field;
+use ir::comp::FieldMethods;
+use ir::derive::CanTriviallyDeriveDebug;
+use ir::comp::CompKind;
+
+/// An analysis that finds for each IR item whether debug cannot be derived.
+///
+/// We use the monotone constraint function `cannot_derive_debug`, defined as
+/// follows:
+///
+/// * If T is Opaque and layout of the type is known, get this layout as opaque
+///   type and check whether it can be derived using trivial checks.
+/// * If T is Array type, debug cannot be derived if the length of the array is
+///   larger than the limit or the type of data the array contains cannot derive
+///   debug.
+/// * If T is a type alias, a templated alias or an indirection to another type,
+///   debug cannot be derived if the type T refers to cannot be derived debug.
+/// * If T is a compound type, debug cannot be derived if any of its base member
+///   or field cannot be derived debug.
+/// * If T is a pointer, T cannot be derived debug if T is a function pointer
+///   and the function signature cannot be derived debug.
+/// * If T is an instantiation of an abstract template definition, T cannot be
+///   derived debug if any of the template arguments or template definition
+///   cannot derive debug.
+#[derive(Debug, Clone)]
+pub struct CannotDeriveDebug<'ctx, 'gen>
+    where 'gen: 'ctx
+{
+    ctx: &'ctx BindgenContext<'gen>,
+
+    // The incremental result of this analysis's computation. Everything in this
+    // set cannot derive debug.
+    cannot_derive_debug: HashSet<ItemId>,
+
+    // Dependencies saying that if a key ItemId has been inserted into the
+    // `cannot_derive_debug` set, then each of the ids in Vec<ItemId> need to be
+    // considered again.
+    //
+    // This is a subset of the natural IR graph with reversed edges, where we
+    // only include the edges from the IR graph that can affect whether a type
+    // can derive debug or not.
+    dependencies: HashMap<ItemId, Vec<ItemId>>,
+}
+
+impl<'ctx, 'gen> CannotDeriveDebug<'ctx, 'gen> {
+    fn consider_edge(kind: EdgeKind) -> bool {
+        match kind {
+            // These are the only edges that can affect whether a type can derive
+            // debug or not.
+            EdgeKind::BaseMember |
+            EdgeKind::Field |
+            EdgeKind::TypeReference |
+            EdgeKind::VarType |
+            EdgeKind::TemplateArgument |
+            EdgeKind::TemplateDeclaration |
+            EdgeKind::TemplateParameterDefinition => true,
+
+            EdgeKind::Constructor |
+            EdgeKind::Destructor |
+            EdgeKind::FunctionReturn |
+            EdgeKind::FunctionParameter |
+            EdgeKind::InnerType |
+            EdgeKind::InnerVar |
+            EdgeKind::Method => false,
+            EdgeKind::Generic => false,
+        }
+    }
+
+    fn insert(&mut self, id: ItemId) -> ConstrainResult {
+        trace!("inserting {:?} into the cannot_derive_debug set", id);
+
+        let was_not_already_in_set = self.cannot_derive_debug.insert(id);
+        assert!(
+            was_not_already_in_set,
+            "We shouldn't try and insert {:?} twice because if it was \
+             already in the set, `constrain` should have exited early.",
+            id
+        );
+
+        ConstrainResult::Changed
+    }
+}
+
+impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDebug<'ctx, 'gen> {
+    type Node = ItemId;
+    type Extra = &'ctx BindgenContext<'gen>;
+    type Output = HashSet<ItemId>;
+
+    fn new(ctx: &'ctx BindgenContext<'gen>) -> CannotDeriveDebug<'ctx, 'gen> {
+        let cannot_derive_debug = HashSet::new();
+        let dependencies = generate_dependencies(ctx, Self::consider_edge);
+
+        CannotDeriveDebug {
+            ctx,
+            cannot_derive_debug,
+            dependencies,
+        }
+    }
+
+    fn initial_worklist(&self) -> Vec<ItemId> {
+        self.ctx.whitelisted_items().iter().cloned().collect()
+    }
+
+    fn constrain(&mut self, id: ItemId) -> ConstrainResult {
+        trace!("constrain: {:?}", id);
+
+        if self.cannot_derive_debug.contains(&id) {
+            trace!("    already know it cannot derive Debug");
+            return ConstrainResult::Same;
+        }
+
+        let item = self.ctx.resolve_item(id);
+        let ty = match item.as_type() {
+            Some(ty) => ty,
+            None => {
+                trace!("    not a type; ignoring");
+                return ConstrainResult::Same;
+            }
+        };
+
+        if ty.is_opaque(self.ctx, item) {
+            let layout_can_derive = ty.layout(self.ctx).map_or(true, |l| {
+                l.opaque().can_trivially_derive_debug(self.ctx, ())
+            });
+            return if layout_can_derive {
+                trace!("    we can trivially derive Debug for the layout");
+                ConstrainResult::Same
+            } else {
+                trace!("    we cannot derive Debug for the layout");
+                self.insert(id)
+            };
+        }
+
+        if ty.layout(self.ctx).map_or(false, |l| l.align > RUST_DERIVE_IN_ARRAY_LIMIT) {
+            // We have to be conservative: the struct *could* have enough
+            // padding that we emit an array that is longer than
+            // `RUST_DERIVE_IN_ARRAY_LIMIT`. If we moved padding calculations
+            // into the IR and computed them before this analysis, then we could
+            // be precise rather than conservative here.
+            return self.insert(id);
+        }
+
+        match *ty.kind() {
+            // Handle the simple cases. These can derive debug without further
+            // information.
+            TypeKind::Void |
+            TypeKind::NullPtr |
+            TypeKind::Int(..) |
+            TypeKind::Float(..) |
+            TypeKind::Complex(..) |
+            TypeKind::Function(..) |
+            TypeKind::Enum(..) |
+            TypeKind::Reference(..) |
+            TypeKind::BlockPointer |
+            TypeKind::Named |
+            TypeKind::UnresolvedTypeRef(..) |
+            TypeKind::ObjCInterface(..) |
+            TypeKind::ObjCId |
+            TypeKind::ObjCSel => {
+                trace!("    simple type that can always derive Debug");
+                ConstrainResult::Same
+            }
+
+            TypeKind::Array(t, len) => {
+                if self.cannot_derive_debug.contains(&t) {
+                    trace!("    arrays of T for which we cannot derive Debug \
+                            also cannot derive Debug");
+                    return self.insert(id);
+                }
+
+                if len <= RUST_DERIVE_IN_ARRAY_LIMIT {
+                    trace!("    array is small enough to derive Debug");
+                    ConstrainResult::Same
+                } else {
+                    trace!("    array is too large to derive Debug");
+                    self.insert(id)
+                }
+            }
+
+            TypeKind::ResolvedTypeRef(t) |
+            TypeKind::TemplateAlias(t, _) |
+            TypeKind::Alias(t) => {
+                if self.cannot_derive_debug.contains(&t) {
+                    trace!("    aliases and type refs to T which cannot derive \
+                            Debug also cannot derive Debug");
+                    self.insert(id)
+                } else {
+                    trace!("    aliases and type refs to T which can derive \
+                            Debug can also derive Debug");
+                    ConstrainResult::Same
+                }
+            }
+
+            TypeKind::Comp(ref info) => {
+                assert!(
+                    !info.has_non_type_template_params(),
+                    "The early ty.is_opaque check should have handled this case"
+                );
+
+                if info.kind() == CompKind::Union {
+                    if self.ctx.options().unstable_rust {
+                        trace!("    cannot derive Debug for Rust unions");
+                        return self.insert(id);
+                    }
+
+                    if ty.layout(self.ctx)
+                        .map_or(true,
+                                |l| l.opaque().can_trivially_derive_debug(self.ctx, ())) {
+                        trace!("    union layout can trivially derive Debug");
+                        return ConstrainResult::Same;
+                    } else {
+                        trace!("    union layout cannot derive Debug");
+                        return self.insert(id);
+                    }
+                }
+
+                let bases_cannot_derive = info.base_members()
+                    .iter()
+                    .any(|base| self.cannot_derive_debug.contains(&base.ty));
+                if bases_cannot_derive {
+                    trace!("    base members cannot derive Debug, so we can't \
+                            either");
+                    return self.insert(id);
+                }
+
+                let fields_cannot_derive = info.fields()
+                    .iter()
+                    .any(|f| {
+                        match *f {
+                            Field::DataMember(ref data) => {
+                                self.cannot_derive_debug.contains(&data.ty())
+                            }
+                            Field::Bitfields(ref bfu) => {
+                                bfu.bitfields()
+                                    .iter().any(|b| {
+                                        self.cannot_derive_debug.contains(&b.ty())
+                                    })
+                            }
+                        }
+                    });
+                if fields_cannot_derive {
+                    trace!("    fields cannot derive Debug, so we can't either");
+                    return self.insert(id);
+                }
+
+                trace!("    comp can derive Debug");
+                ConstrainResult::Same
+            }
+
+            TypeKind::Pointer(inner) => {
+                let inner_type = self.ctx.resolve_type(inner).canonical_type(self.ctx);
+                if let TypeKind::Function(ref sig) = *inner_type.kind() {
+                    if !sig.can_trivially_derive_debug(&self.ctx, ()) {
+                        trace!("    function pointer that can't trivially derive Debug");
+                        return self.insert(id);
+                    }
+                }
+                trace!("    pointers can derive Debug");
+                ConstrainResult::Same
+            }
+
+            TypeKind::TemplateInstantiation(ref template) => {
+                let args_cannot_derive = template.template_arguments()
+                    .iter()
+                    .any(|arg| self.cannot_derive_debug.contains(&arg));
+                if args_cannot_derive {
+                    trace!("    template args cannot derive Debug, so \
+                            insantiation can't either");
+                    return self.insert(id);
+                }
+
+                assert!(
+                    !template.template_definition().is_opaque(self.ctx, &()),
+                    "The early ty.is_opaque check should have handled this case"
+                );
+                let def_cannot_derive = self.cannot_derive_debug
+                    .contains(&template.template_definition());
+                if def_cannot_derive {
+                    trace!("    template definition cannot derive Debug, so \
+                            insantiation can't either");
+                    return self.insert(id);
+                }
+
+                trace!("    template instantiation can derive Debug");
+                ConstrainResult::Same
+            }
+
+            TypeKind::Opaque => {
+                unreachable!(
+                    "The early ty.is_opaque check should have handled this case"
+                )
+            }
+        }
+    }
+
+    fn each_depending_on<F>(&self, id: ItemId, mut f: F)
+        where F: FnMut(ItemId),
+    {
+        if let Some(edges) = self.dependencies.get(&id) {
+            for item in edges {
+                trace!("enqueue {:?} into worklist", item);
+                f(*item);
+            }
+        }
+    }
+}
+
+impl<'ctx, 'gen> From<CannotDeriveDebug<'ctx, 'gen>> for HashSet<ItemId> {
+    fn from(analysis: CannotDeriveDebug<'ctx, 'gen>) -> Self {
+        analysis.cannot_derive_debug
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/bindgen/src/ir/analysis/has_vtable.rs
@@ -0,0 +1,162 @@
+//! Determining which types has vtable
+use super::{ConstrainResult, MonotoneFramework, generate_dependencies};
+use std::collections::HashSet;
+use std::collections::HashMap;
+use ir::context::{BindgenContext, ItemId};
+use ir::traversal::EdgeKind;
+use ir::ty::TypeKind;
+
+/// An analysis that finds for each IR item whether it has vtable or not
+///
+/// We use the monotone function `has vtable`, defined as follows:
+///
+/// * If T is a type alias, a templated alias, an indirection to another type,
+///   or a reference of a type, T has vtable if the type T refers to has vtable.
+/// * If T is a compound type, T has vtable if we saw a virtual function when
+///   parsing it or any of its base member has vtable.
+/// * If T is an instantiation of an abstract template definition, T has
+///   vtable if template definition has vtable
+#[derive(Debug, Clone)]
+pub struct HasVtableAnalysis<'ctx, 'gen>
+    where 'gen: 'ctx
+{
+    ctx: &'ctx BindgenContext<'gen>,
+
+    // The incremental result of this analysis's computation. Everything in this
+    // set definitely has a vtable.
+    have_vtable: HashSet<ItemId>,
+
+    // Dependencies saying that if a key ItemId has been inserted into the
+    // `have_vtable` set, then each of the ids in Vec<ItemId> need to be
+    // considered again.
+    //
+    // This is a subset of the natural IR graph with reversed edges, where we
+    // only include the edges from the IR graph that can affect whether a type
+    // has a vtable or not.
+    dependencies: HashMap<ItemId, Vec<ItemId>>,
+}
+
+impl<'ctx, 'gen> HasVtableAnalysis<'ctx, 'gen> {
+    fn consider_edge(kind: EdgeKind) -> bool {
+        match kind {
+            // These are the only edges that can affect whether a type has a
+            // vtable or not.
+            EdgeKind::TypeReference |
+            EdgeKind::BaseMember |
+            EdgeKind::TemplateDeclaration => true,
+            _ => false,
+        }
+    }
+
+    fn insert(&mut self, id: ItemId) -> ConstrainResult {
+        let was_not_already_in_set = self.have_vtable.insert(id);
+        assert!(
+            was_not_already_in_set,
+            "We shouldn't try and insert {:?} twice because if it was \
+             already in the set, `constrain` should have exited early.",
+            id
+        );
+        ConstrainResult::Changed
+    }
+}
+
+impl<'ctx, 'gen> MonotoneFramework for HasVtableAnalysis<'ctx, 'gen> {
+    type Node = ItemId;
+    type Extra = &'ctx BindgenContext<'gen>;
+    type Output = HashSet<ItemId>;
+
+    fn new(ctx: &'ctx BindgenContext<'gen>) -> HasVtableAnalysis<'ctx, 'gen> {
+        let have_vtable = HashSet::new();
+        let dependencies = generate_dependencies(ctx, Self::consider_edge);
+
+        HasVtableAnalysis {
+            ctx,
+            have_vtable,
+            dependencies,
+        }
+    }
+
+    fn initial_worklist(&self) -> Vec<ItemId> {
+        self.ctx.whitelisted_items().iter().cloned().collect()
+    }
+
+    fn constrain(&mut self, id: ItemId) -> ConstrainResult {
+        if self.have_vtable.contains(&id) {
+            // We've already computed that this type has a vtable and that can't
+            // change.
+            return ConstrainResult::Same;
+        }
+
+        let item = self.ctx.resolve_item(id);
+        let ty = match item.as_type() {
+            None => return ConstrainResult::Same,
+            Some(ty) => ty
+        };
+
+        // TODO #851: figure out a way to handle deriving from template type parameters.
+        match *ty.kind() {
+            TypeKind::TemplateAlias(t, _) |
+            TypeKind::Alias(t) |
+            TypeKind::ResolvedTypeRef(t) |
+            TypeKind::Reference(t) => {
+                if self.have_vtable.contains(&t) {
+                    self.insert(id)
+                } else {
+                    ConstrainResult::Same
+                }
+            },
+
+            TypeKind::Comp(ref info) => {
+                if info.has_own_virtual_method() {
+                    return self.insert(id);
+                }
+                let bases_has_vtable = info.base_members().iter().any(|base| {
+                    self.have_vtable.contains(&base.ty)
+                });
+                if bases_has_vtable {
+                    self.insert(id)
+                } else {
+                    ConstrainResult::Same
+                }
+            },
+
+            TypeKind::TemplateInstantiation(ref inst) => {
+                if self.have_vtable.contains(&inst.template_definition()) {
+                    self.insert(id)
+                } else {
+                    ConstrainResult::Same
+                }
+            },
+
+            _ => ConstrainResult::Same,
+        }
+    }
+
+    fn each_depending_on<F>(&self, id: ItemId, mut f: F)
+        where F: FnMut(ItemId),
+    {
+        if let Some(edges) = self.dependencies.get(&id) {
+            for item in edges {
+                trace!("enqueue {:?} into worklist", item);
+                f(*item);
+            }
+        }
+    }
+}
+
+impl<'ctx, 'gen> From<HasVtableAnalysis<'ctx, 'gen>> for HashSet<ItemId> {
+    fn from(analysis: HasVtableAnalysis<'ctx, 'gen>) -> Self {
+        analysis.have_vtable
+    }
+}
+
+/// A convenience trait for the things for which we might wonder if they have a
+/// vtable during codegen.
+///
+/// This is not for _computing_ whether the thing has a vtable, it is for
+/// looking up the results of the HasVtableAnalysis's computations for a
+/// specific thing.
+pub trait HasVtable {
+    /// Return `true` if this thing has vtable, `false` otherwise.
+    fn has_vtable(&self, ctx: &BindgenContext) -> bool;
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/bindgen/src/ir/analysis/mod.rs
@@ -0,0 +1,345 @@
+//! Fix-point analyses on the IR using the "monotone framework".
+//!
+//! A lattice is a set with a partial ordering between elements, where there is
+//! a single least upper bound and a single greatest least bound for every
+//! subset. We are dealing with finite lattices, which means that it has a
+//! finite number of elements, and it follows that there exists a single top and
+//! a single bottom member of the lattice. For example, the power set of a
+//! finite set forms a finite lattice where partial ordering is defined by set
+//! inclusion, that is `a <= b` if `a` is a subset of `b`. Here is the finite
+//! lattice constructed from the set {0,1,2}:
+//!
+//! ```text
+//!                    .----- Top = {0,1,2} -----.
+//!                   /            |              \
+//!                  /             |               \
+//!                 /              |                \
+//!              {0,1} -------.  {0,2}  .--------- {1,2}
+//!                |           \ /   \ /             |
+//!                |            /     \              |
+//!                |           / \   / \             |
+//!               {0} --------'   {1}   `---------- {2}
+//!                 \              |                /
+//!                  \             |               /
+//!                   \            |              /
+//!                    `------ Bottom = {} ------'
+//! ```
+//!
+//! A monotone function `f` is a function where if `x <= y`, then it holds that
+//! `f(x) <= f(y)`. It should be clear that running a monotone function to a
+//! fix-point on a finite lattice will always terminate: `f` can only "move"
+//! along the lattice in a single direction, and therefore can only either find
+//! a fix-point in the middle of the lattice or continue to the top or bottom
+//! depending if it is ascending or descending the lattice respectively.
+//!
+//! For a deeper introduction to the general form of this kind of analysis, see
+//! [Static Program Analysis by Anders Møller and Michael I. Schwartzbach][spa].
+//!
+//! [spa]: https://cs.au.dk/~amoeller/spa/spa.pdf
+
+// Re-export individual analyses.
+mod template_params;
+pub use self::template_params::UsedTemplateParameters;
+mod derive_debug;
+pub use self::derive_debug::CannotDeriveDebug;
+mod has_vtable;
+pub use self::has_vtable::HasVtableAnalysis;
+pub use self::has_vtable::HasVtable;
+
+use ir::context::{BindgenContext, ItemId};
+use ir::traversal::{EdgeKind, Trace};
+use std::collections::HashMap;
+use std::fmt;
+
+/// An analysis in the monotone framework.
+///
+/// Implementors of this trait must maintain the following two invariants:
+///
+/// 1. The concrete data must be a member of a finite-height lattice.
+/// 2. The concrete `constrain` method must be monotone: that is,
+///    if `x <= y`, then `constrain(x) <= constrain(y)`.
+///
+/// If these invariants do not hold, iteration to a fix-point might never
+/// complete.
+///
+/// For a simple example analysis, see the `ReachableFrom` type in the `tests`
+/// module below.
+pub trait MonotoneFramework: Sized + fmt::Debug {
+    /// The type of node in our dependency graph.
+    ///
+    /// This is just generic (and not `ItemId`) so that we can easily unit test
+    /// without constructing real `Item`s and their `ItemId`s.
+    type Node: Copy;
+
+    /// Any extra data that is needed during computation.
+    ///
+    /// Again, this is just generic (and not `&BindgenContext`) so that we can
+    /// easily unit test without constructing real `BindgenContext`s full of
+    /// real `Item`s and real `ItemId`s.
+    type Extra: Sized;
+
+    /// The final output of this analysis. Once we have reached a fix-point, we
+    /// convert `self` into this type, and return it as the final result of the
+    /// analysis.
+    type Output: From<Self> + fmt::Debug;
+
+    /// Construct a new instance of this analysis.
+    fn new(extra: Self::Extra) -> Self;
+
+    /// Get the initial set of nodes from which to start the analysis. Unless
+    /// you are sure of some domain-specific knowledge, this should be the
+    /// complete set of nodes.
+    fn initial_worklist(&self) -> Vec<Self::Node>;
+
+    /// Update the analysis for the given node.
+    ///
+    /// If this results in changing our internal state (ie, we discovered that
+    /// we have not reached a fix-point and iteration should continue), return
+    /// `ConstrainResult::Changed`. Otherwise, return `ConstrainResult::Same`.
+    /// When `constrain` returns `ConstrainResult::Same` for all nodes in the
+    /// set, we have reached a fix-point and the analysis is complete.
+    fn constrain(&mut self, node: Self::Node) -> ConstrainResult;
+
+    /// For each node `d` that depends on the given `node`'s current answer when
+    /// running `constrain(d)`, call `f(d)`. This informs us which new nodes to
+    /// queue up in the worklist when `constrain(node)` reports updated
+    /// information.
+    fn each_depending_on<F>(&self, node: Self::Node, f: F)
+        where F: FnMut(Self::Node);
+}
+
+/// Whether an analysis's `constrain` function modified the incremental results
+/// or not.
+pub enum ConstrainResult {
+    /// The incremental results were updated, and the fix-point computation
+    /// should continue.
+    Changed,
+
+    /// The incremental results were not updated.
+    Same,
+}
+
+/// Run an analysis in the monotone framework.
+pub fn analyze<Analysis>(extra: Analysis::Extra) -> Analysis::Output
+    where Analysis: MonotoneFramework,
+{
+    let mut analysis = Analysis::new(extra);
+    let mut worklist = analysis.initial_worklist();
+
+    while let Some(node) = worklist.pop() {
+        if let ConstrainResult::Changed = analysis.constrain(node) {
+            analysis.each_depending_on(node, |needs_work| {
+                worklist.push(needs_work);
+            });
+        }
+    }
+
+    analysis.into()
+}
+
+/// Generate the dependency map for analysis
+pub fn generate_dependencies<F>(ctx: &BindgenContext, consider_edge: F) -> HashMap<ItemId, Vec<ItemId>>
+    where F: Fn(EdgeKind) -> bool {
+    let mut dependencies = HashMap::new();
+
+    for &item in ctx.whitelisted_items() {
+        dependencies.entry(item).or_insert(vec![]);
+
+        {
+            // We reverse our natural IR graph edges to find dependencies
+            // between nodes.
+            item.trace(ctx, &mut |sub_item: ItemId, edge_kind| {
+                if ctx.whitelisted_items().contains(&sub_item) &&
+                    consider_edge(edge_kind) {
+                        dependencies.entry(sub_item)
+                            .or_insert(vec![])
+                            .push(item);
+                    }
+            }, &());
+        }
+    }
+    dependencies
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use std::collections::{HashMap, HashSet};
+
+    // Here we find the set of nodes that are reachable from any given
+    // node. This is a lattice mapping nodes to subsets of all nodes. Our join
+    // function is set union.
+    //
+    // This is our test graph:
+    //
+    //     +---+                    +---+
+    //     |   |                    |   |
+    //     | 1 |               .----| 2 |
+    //     |   |               |    |   |
+    //     +---+               |    +---+
+    //       |                 |      ^
+    //       |                 |      |
+    //       |      +---+      '------'
+    //       '----->|   |
+    //              | 3 |
+    //       .------|   |------.
+    //       |      +---+      |
+    //       |        ^        |
+    //       v        |        v
+    //     +---+      |      +---+    +---+
+    //     |   |      |      |   |    |   |
+    //     | 4 |      |      | 5 |--->| 6 |
+    //     |   |      |      |   |    |   |
+    //     +---+      |      +---+    +---+
+    //       |        |        |        |
+    //       |        |        |        v
+    //       |      +---+      |      +---+
+    //       |      |   |      |      |   |
+    //       '----->| 7 |<-----'      | 8 |
+    //              |   |             |   |
+    //              +---+             +---+
+    //
+    // And here is the mapping from a node to the set of nodes that are
+    // reachable from it within the test graph:
+    //
+    //     1: {3,4,5,6,7,8}
+    //     2: {2}
+    //     3: {3,4,5,6,7,8}
+    //     4: {3,4,5,6,7,8}
+    //     5: {3,4,5,6,7,8}
+    //     6: {8}
+    //     7: {3,4,5,6,7,8}
+    //     8: {}
+
+    #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
+    struct Node(usize);
+
+    #[derive(Clone, Debug, Default, PartialEq, Eq)]
+    struct Graph(HashMap<Node, Vec<Node>>);
+
+    impl Graph {
+        fn make_test_graph() -> Graph {
+            let mut g = Graph::default();
+            g.0.insert(Node(1), vec![Node(3)]);
+            g.0.insert(Node(2), vec![Node(2)]);
+            g.0.insert(Node(3), vec![Node(4), Node(5)]);
+            g.0.insert(Node(4), vec![Node(7)]);
+            g.0.insert(Node(5), vec![Node(6), Node(7)]);
+            g.0.insert(Node(6), vec![Node(8)]);
+            g.0.insert(Node(7), vec![Node(3)]);
+            g.0.insert(Node(8), vec![]);
+            g
+        }
+
+        fn reverse(&self) -> Graph {
+            let mut reversed = Graph::default();
+            for (node, edges) in self.0.iter() {
+                reversed.0.entry(*node).or_insert(vec![]);
+                for referent in edges.iter() {
+                    reversed.0.entry(*referent).or_insert(vec![]).push(*node);
+                }
+            }
+            reversed
+        }
+    }
+
+    #[derive(Clone, Debug, PartialEq, Eq)]
+    struct ReachableFrom<'a> {
+        reachable: HashMap<Node, HashSet<Node>>,
+        graph: &'a Graph,
+        reversed: Graph,
+    }
+
+    impl<'a> MonotoneFramework for ReachableFrom<'a> {
+        type Node = Node;
+        type Extra = &'a Graph;
+        type Output = HashMap<Node, HashSet<Node>>;
+
+        fn new(graph: &'a Graph) -> ReachableFrom {
+            let reversed = graph.reverse();
+            ReachableFrom {
+                reachable: Default::default(),
+                graph: graph,
+                reversed: reversed,
+            }
+        }
+
+        fn initial_worklist(&self) -> Vec<Node> {
+            self.graph.0.keys().cloned().collect()
+        }
+
+        fn constrain(&mut self, node: Node) -> ConstrainResult {
+            // The set of nodes reachable from a node `x` is
+            //
+            //     reachable(x) = s_0 U s_1 U ... U reachable(s_0) U reachable(s_1) U ...
+            //
+            // where there exist edges from `x` to each of `s_0, s_1, ...`.
+            //
+            // Yes, what follows is a **terribly** inefficient set union
+            // implementation. Don't copy this code outside of this test!
+
+            let original_size =
+                self.reachable.entry(node).or_insert(HashSet::new()).len();
+
+            for sub_node in self.graph.0[&node].iter() {
+                self.reachable.get_mut(&node).unwrap().insert(*sub_node);
+
+                let sub_reachable = self.reachable
+                    .entry(*sub_node)
+                    .or_insert(HashSet::new())
+                    .clone();
+
+                for transitive in sub_reachable {
+                    self.reachable.get_mut(&node).unwrap().insert(transitive);
+                }
+            }
+
+            let new_size = self.reachable[&node].len();
+            if original_size != new_size {
+                ConstrainResult::Changed
+            } else {
+                ConstrainResult::Same
+            }
+        }
+
+        fn each_depending_on<F>(&self, node: Node, mut f: F)
+            where F: FnMut(Node),
+        {
+            for dep in self.reversed.0[&node].iter() {
+                f(*dep);
+            }
+        }
+    }
+
+    impl<'a> From<ReachableFrom<'a>> for HashMap<Node, HashSet<Node>> {
+        fn from(reachable: ReachableFrom<'a>) -> Self {
+            reachable.reachable
+        }
+    }
+
+    #[test]
+    fn monotone() {
+        let g = Graph::make_test_graph();
+        let reachable = analyze::<ReachableFrom>(&g);
+        println!("reachable = {:#?}", reachable);
+
+        fn nodes<A>(nodes: A) -> HashSet<Node>
+            where A: AsRef<[usize]>,
+        {
+            nodes.as_ref().iter().cloned().map(Node).collect()
+        }
+
+        let mut expected = HashMap::new();
+        expected.insert(Node(1), nodes([3, 4, 5, 6, 7, 8]));
+        expected.insert(Node(2), nodes([2]));
+        expected.insert(Node(3), nodes([3, 4, 5, 6, 7, 8]));
+        expected.insert(Node(4), nodes([3, 4, 5, 6, 7, 8]));
+        expected.insert(Node(5), nodes([3, 4, 5, 6, 7, 8]));
+        expected.insert(Node(6), nodes([8]));
+        expected.insert(Node(7), nodes([3, 4, 5, 6, 7, 8]));
+        expected.insert(Node(8), nodes([]));
+        println!("expected = {:#?}", expected);
+
+        assert_eq!(reachable, expected);
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/bindgen/src/ir/analysis/template_params.rs
@@ -0,0 +1,550 @@
+//! Discover which template type parameters are actually used.
+//!
+//! ### Why do we care?
+//!
+//! C++ allows ignoring template parameters, while Rust does not. Usually we can
+//! blindly stick a `PhantomData<T>` inside a generic Rust struct to make up for
+//! this. That doesn't work for templated type aliases, however:
+//!
+//! ```C++
+//! template <typename T>
+//! using Fml = int;
+//! ```
+//!
+//! If we generate the naive Rust code for this alias, we get:
+//!
+//! ```ignore
+//! pub type Fml<T> = ::std::os::raw::int;
+//! ```
+//!
+//! And this is rejected by `rustc` due to the unused type parameter.
+//!
+//! (Aside: in these simple cases, `libclang` will often just give us the
+//! aliased type directly, and we will never even know we were dealing with
+//! aliases, let alone templated aliases. It's the more convoluted scenarios
+//! where we get to have some fun...)
+//!
+//! For such problematic template aliases, we could generate a tuple whose
+//! second member is a `PhantomData<T>`. Or, if we wanted to go the extra mile,
+//! we could even generate some smarter wrapper that implements `Deref`,
+//! `DerefMut`, `From`, `Into`, `AsRef`, and `AsMut` to the actually aliased
+//! type. However, this is still lackluster:
+//!
+//! 1. Even with a billion conversion-trait implementations, using the generated
+//!    bindings is rather un-ergonomic.
+//! 2. With either of these solutions, we need to keep track of which aliases
+//!    we've transformed like this in order to generate correct uses of the
+//!    wrapped type.
+//!
+//! Given that we have to properly track which template parameters ended up used
+//! for (2), we might as well leverage that information to make ergonomic
+//! bindings that don't contain any unused type parameters at all, and
+//! completely avoid the pain of (1).
+//!
+//! ### How do we determine which template parameters are used?
+//!
+//! Determining which template parameters are actually used is a trickier
+//! problem than it might seem at a glance. On the one hand, trivial uses are
+//! easy to detect:
+//!
+//! ```C++
+//! template <typename T>
+//! class Foo {
+//!     T trivial_use_of_t;
+//! };
+//! ```
+//!
+//! It gets harder when determining if one template parameter is used depends on
+//! determining if another template parameter is used. In this example, whether
+//! `U` is used depends on whether `T` is used.
+//!
+//! ```C++
+//! template <typename T>
+//! class DoesntUseT {
+//!     int x;
+//! };
+//!
+//! template <typename U>
+//! class Fml {
+//!     DoesntUseT<U> lololol;
+//! };
+//! ```
+//!
+//! We can express the set of used template parameters as a constraint solving
+//! problem (where the set of template parameters used by a given IR item is the
+//! union of its sub-item's used template parameters) and iterate to a
+//! fixed-point.
+//!
+//! We use the `ir::analysis::MonotoneFramework` infrastructure for this
+//! fix-point analysis, where our lattice is the mapping from each IR item to
+//! the powerset of the template parameters that appear in the input C++ header,
+//! our join function is set union. The set of template parameters appearing in
+//! the program is finite, as is the number of IR items. We start at our
+//! lattice's bottom element: every item mapping to an empty set of template
+//! parameters. Our analysis only adds members to each item's set of used
+//! template parameters, never removes them, so it is monotone. Because our
+//! lattice is finite and our constraint function is monotone, iteration to a
+//! fix-point will terminate.
+//!
+//! See `src/ir/analysis.rs` for more.
+
+use super::{ConstrainResult, MonotoneFramework};
+use ir::context::{BindgenContext, ItemId};
+use ir::item::{Item, ItemSet};
+use ir::template::{TemplateInstantiation, TemplateParameters};
+use ir::traversal::{EdgeKind, Trace};
+use ir::ty::TypeKind;
+use std::collections::{HashMap, HashSet};
+
+/// An analysis that finds for each IR item its set of template parameters that
+/// it uses.
+///
+/// We use the monotone constraint function `template_param_usage`, defined as
+/// follows:
+///
+/// * If `T` is a named template type parameter, it trivially uses itself:
+///
+/// ```ignore
+/// template_param_usage(T) = { T }
+/// ```
+///
+/// * If `inst` is a template instantiation, `inst.args` are the template
+///   instantiation's template arguments, `inst.def` is the template definition
+///   being instantiated, and `inst.def.params` is the template definition's
+///   template parameters, then the instantiation's usage is the union of each
+///   of its arguments' usages *if* the corresponding template parameter is in
+///   turn used by the template definition:
+///
+/// ```ignore
+/// template_param_usage(inst) = union(
+///     template_param_usage(inst.args[i])
+///         for i in 0..length(inst.args.length)
+///             if inst.def.params[i] in template_param_usage(inst.def)
+/// )
+/// ```
+///
+/// * Finally, for all other IR item kinds, we use our lattice's `join`
+/// operation: set union with each successor of the given item's template
+/// parameter usage:
+///
+/// ```ignore
+/// template_param_usage(v) =
+///     union(template_param_usage(w) for w in successors(v))
+/// ```
+///
+/// Note that we ignore certain edges in the graph, such as edges from a
+/// template declaration to its template parameters' definitions for this
+/// analysis. If we didn't, then we would mistakenly determine that ever
+/// template parameter is always used.
+///
+/// The final wrinkle is handling of blacklisted types. Normally, we say that
+/// the set of whitelisted items is the transitive closure of items explicitly
+/// called out for whitelisting, *without* any items explicitly called out as
+/// blacklisted. However, for the purposes of this analysis's correctness, we
+/// simplify and consider run the analysis on the full transitive closure of
+/// whitelisted items. We do, however, treat instantiations of blacklisted items
+/// specially; see `constrain_instantiation_of_blacklisted_template` and its
+/// documentation for details.
+#[derive(Debug, Clone)]
+pub struct UsedTemplateParameters<'ctx, 'gen>
+    where 'gen: 'ctx,
+{
+    ctx: &'ctx BindgenContext<'gen>,
+
+    // The Option is only there for temporary moves out of the hash map. See the
+    // comments in `UsedTemplateParameters::constrain` below.
+    used: HashMap<ItemId, Option<ItemSet>>,
+
+    dependencies: HashMap<ItemId, Vec<ItemId>>,
+
+    // The set of whitelisted items, without any blacklisted items reachable
+    // from the whitelisted items which would otherwise be considered
+    // whitelisted as well.
+    whitelisted_items: HashSet<ItemId>,
+}
+
+impl<'ctx, 'gen> UsedTemplateParameters<'ctx, 'gen> {
+    fn consider_edge(kind: EdgeKind) -> bool {
+        match kind {
+            // For each of these kinds of edges, if the referent uses a template
+            // parameter, then it should be considered that the origin of the
+            // edge also uses the template parameter.
+            EdgeKind::TemplateArgument |
+            EdgeKind::BaseMember |
+            EdgeKind::Field |
+            EdgeKind::Constructor |
+            EdgeKind::Destructor |
+            EdgeKind::VarType |
+            EdgeKind::FunctionReturn |
+            EdgeKind::FunctionParameter |
+            EdgeKind::TypeReference => true,
+
+            // An inner var or type using a template parameter is orthogonal
+            // from whether we use it. See template-param-usage-{6,11}.hpp.
+            EdgeKind::InnerVar | EdgeKind::InnerType => false,
+
+            // We can't emit machine code for new monomorphizations of class
+            // templates' methods (and don't detect explicit instantiations) so
+            // we must ignore template parameters that are only used by
+            // methods. This doesn't apply to a function type's return or
+            // parameter types, however, because of type aliases of function
+            // pointers that use template parameters, eg
+            // tests/headers/struct_with_typedef_template_arg.hpp
+            EdgeKind::Method => false,
+
+            // If we considered these edges, we would end up mistakenly claiming
+            // that every template parameter always used.
+            EdgeKind::TemplateDeclaration |
+            EdgeKind::TemplateParameterDefinition => false,
+
+            // Since we have to be careful about which edges we consider for
+            // this analysis to be correct, we ignore generic edges. We also
+            // avoid a `_` wild card to force authors of new edge kinds to
+            // determine whether they need to be considered by this analysis.
+            EdgeKind::Generic => false,
+        }
+    }
+
+    fn take_this_id_usage_set(&mut self, this_id: ItemId) -> ItemSet {
+        self.used
+            .get_mut(&this_id)
+            .expect("Should have a set of used template params for every item \
+                     id")
+            .take()
+            .expect("Should maintain the invariant that all used template param \
+                     sets are `Some` upon entry of `constrain`")
+    }
+
+    /// We say that blacklisted items use all of their template parameters. The
+    /// blacklisted type is most likely implemented explicitly by the user,
+    /// since it won't be in the generated bindings, and we don't know exactly
+    /// what they'll to with template parameters, but we can push the issue down
+    /// the line to them.
+    fn constrain_instantiation_of_blacklisted_template(&self,
+                                                       this_id: ItemId,
+                                                       used_by_this_id: &mut ItemSet,
+                                                       instantiation: &TemplateInstantiation) {
+        trace!("    instantiation of blacklisted template, uses all template \
+                arguments");
+
+        let args = instantiation.template_arguments()
+            .into_iter()
+            .map(|a| {
+                a.into_resolver()
+                    .through_type_refs()
+                    .through_type_aliases()
+                    .resolve(self.ctx)
+                    .id()
+            })
+            .filter(|a| *a != this_id)
+            .flat_map(|a| {
+                self.used.get(&a)
+                    .expect("Should have a used entry for the template arg")
+                    .as_ref()
+                    .expect("Because a != this_id, and all used template \
+                             param sets other than this_id's are `Some`, \
+                             a's used template param set should be `Some`")
+                    .iter()
+                    .cloned()
+            });
+
+        used_by_this_id.extend(args);
+    }
+
+    /// A template instantiation's concrete template argument is only used if
+    /// the template definition uses the corresponding template parameter.
+    fn constrain_instantiation(&self,
+                               this_id: ItemId,
+                               used_by_this_id: &mut ItemSet,
+                               instantiation: &TemplateInstantiation) {
+        trace!("    template instantiation");
+
+        let decl = self.ctx.resolve_type(instantiation.template_definition());
+        let args = instantiation.template_arguments();
+
+        let params = decl.self_template_params(self.ctx)
+            .unwrap_or(vec![]);
+
+        debug_assert!(this_id != instantiation.template_definition());
+        let used_by_def = self.used
+            .get(&instantiation.template_definition())
+            .expect("Should have a used entry for instantiation's template definition")
+            .as_ref()
+            .expect("And it should be Some because only this_id's set is None, and an \
+                     instantiation's template definition should never be the \
+                     instantiation itself");
+
+        for (arg, param) in args.iter().zip(params.iter()) {
+            trace!("      instantiation's argument {:?} is used if definition's \
+                    parameter {:?} is used",
+                   arg,
+                   param);
+
+            if used_by_def.contains(param) {
+                trace!("        param is used by template definition");
+
+                let arg = arg.into_resolver()
+                    .through_type_refs()
+                    .through_type_aliases()
+                    .resolve(self.ctx)
+                    .id();
+
+                if arg == this_id {
+                    continue;
+                }
+
+                let used_by_arg = self.used
+                    .get(&arg)
+                    .expect("Should have a used entry for the template arg")
+                    .as_ref()
+                    .expect("Because arg != this_id, and all used template \
+                             param sets other than this_id's are `Some`, \
+                             arg's used template param set should be \
+                             `Some`")
+                    .iter()
+                    .cloned();
+                used_by_this_id.extend(used_by_arg);
+            }
+        }
+    }
+
+    /// The join operation on our lattice: the set union of all of this id's
+    /// successors.
+    fn constrain_join(&self, used_by_this_id: &mut ItemSet, item: &Item) {
+        trace!("    other item: join with successors' usage");
+
+        item.trace(self.ctx, &mut |sub_id, edge_kind| {
+            // Ignore ourselves, since union with ourself is a
+            // no-op. Ignore edges that aren't relevant to the
+            // analysis.
+            if sub_id == item.id() || !Self::consider_edge(edge_kind) {
+                return;
+            }
+
+            let used_by_sub_id = self.used
+                .get(&sub_id)
+                .expect("Should have a used set for the sub_id successor")
+                .as_ref()
+                .expect("Because sub_id != id, and all used template \
+                         param sets other than id's are `Some`, \
+                         sub_id's used template param set should be \
+                         `Some`")
+                        .iter()
+                        .cloned();
+
+            trace!("      union with {:?}'s usage: {:?}",
+                   sub_id,
+                   used_by_sub_id.clone().collect::<Vec<_>>());
+
+            used_by_this_id.extend(used_by_sub_id);
+        }, &());
+    }
+}
+
+impl<'ctx, 'gen> MonotoneFramework for UsedTemplateParameters<'ctx, 'gen> {
+    type Node = ItemId;
+    type Extra = &'ctx BindgenContext<'gen>;
+    type Output = HashMap<ItemId, ItemSet>;
+
+    fn new(ctx: &'ctx BindgenContext<'gen>)
+           -> UsedTemplateParameters<'ctx, 'gen> {
+        let mut used = HashMap::new();
+        let mut dependencies = HashMap::new();
+        let whitelisted_items: HashSet<_> = ctx.whitelisted_items()
+            .iter()
+            .cloned()
+            .collect();
+
+        let whitelisted_and_blacklisted_items: ItemSet = whitelisted_items.iter()
+            .cloned()
+            .flat_map(|i| {
+                let mut reachable = vec![i];
+                i.trace(ctx, &mut |s, _| {
+                    reachable.push(s);
+                }, &());
+                reachable
+            })
+            .collect();
+
+        for item in whitelisted_and_blacklisted_items {
+            dependencies.entry(item).or_insert(vec![]);
+            used.entry(item).or_insert(Some(ItemSet::new()));
+
+            {
+                // We reverse our natural IR graph edges to find dependencies
+                // between nodes.
+                item.trace(ctx, &mut |sub_item: ItemId, _| {
+                    used.entry(sub_item).or_insert(Some(ItemSet::new()));
+                    dependencies.entry(sub_item)
+                        .or_insert(vec![])
+                        .push(item);
+                }, &());
+            }
+
+            // Additionally, whether a template instantiation's template
+            // arguments are used depends on whether the template declaration's
+            // generic template parameters are used.
+            ctx.resolve_item(item)
+                .as_type()
+                .map(|ty| match ty.kind() {
+                    &TypeKind::TemplateInstantiation(ref inst) => {
+                        let decl = ctx.resolve_type(inst.template_definition());
+                        let args = inst.template_arguments();
+
+                        // Although template definitions should always have
+                        // template parameters, there is a single exception:
+                        // opaque templates. Hence the unwrap_or.
+                        let params = decl.self_template_params(ctx)
+                            .unwrap_or(vec![]);
+
+                        for (arg, param) in args.iter().zip(params.iter()) {
+                            let arg = arg.into_resolver()
+                                .through_type_aliases()
+                                .through_type_refs()
+                                .resolve(ctx)
+                                .id();
+
+                            let param = param.into_resolver()
+                                .through_type_aliases()
+                                .through_type_refs()
+                                .resolve(ctx)
+                                .id();
+
+                            used.entry(arg).or_insert(Some(ItemSet::new()));
+                            used.entry(param).or_insert(Some(ItemSet::new()));
+
+                            dependencies.entry(arg)
+                                .or_insert(vec![])
+                                .push(param);
+                        }
+                    }
+                    _ => {}
+                });
+        }
+
+        if cfg!(feature = "testing_only_extra_assertions") {
+            // Invariant: The `used` map has an entry for every whitelisted
+            // item, as well as all explicitly blacklisted items that are
+            // reachable from whitelisted items.
+            //
+            // Invariant: the `dependencies` map has an entry for every
+            // whitelisted item.
+            //
+            // (This is so that every item we call `constrain` on is guaranteed
+            // to have a set of template parameters, and we can allow
+            // blacklisted templates to use all of their parameters).
+            for item in whitelisted_items.iter() {
+                extra_assert!(used.contains_key(item));
+                extra_assert!(dependencies.contains_key(item));
+                item.trace(ctx, &mut |sub_item, _| {
+                    extra_assert!(used.contains_key(&sub_item));
+                    extra_assert!(dependencies.contains_key(&sub_item));
+                }, &())
+            }
+        }
+
+        UsedTemplateParameters {
+            ctx: ctx,
+            used: used,
+            dependencies: dependencies,
+            whitelisted_items: whitelisted_items,
+        }
+    }
+
+    fn initial_worklist(&self) -> Vec<ItemId> {
+        // The transitive closure of all whitelisted items, including explicitly
+        // blacklisted items.
+        self.ctx
+            .whitelisted_items()
+            .iter()
+            .cloned()
+            .flat_map(|i| {
+                let mut reachable = vec![i];
+                i.trace(self.ctx, &mut |s, _| {
+                    reachable.push(s);
+                }, &());
+                reachable
+            })
+            .collect()
+    }
+
+    fn constrain(&mut self, id: ItemId) -> ConstrainResult {
+        // Invariant: all hash map entries' values are `Some` upon entering and
+        // exiting this method.
+        extra_assert!(self.used.values().all(|v| v.is_some()));
+
+        // Take the set for this id out of the hash map while we mutate it based
+        // on other hash map entries. We *must* put it back into the hash map at
+        // the end of this method. This allows us to side-step HashMap's lack of
+        // an analog to slice::split_at_mut.
+        let mut used_by_this_id = self.take_this_id_usage_set(id);
+
+        trace!("constrain {:?}", id);
+        trace!("  initially, used set is {:?}", used_by_this_id);
+
+        let original_len = used_by_this_id.len();
+
+        let item = self.ctx.resolve_item(id);
+        let ty_kind = item.as_type().map(|ty| ty.kind());
+        match ty_kind {
+            // Named template type parameters trivially use themselves.
+            Some(&TypeKind::Named) => {
+                trace!("    named type, trivially uses itself");
+                used_by_this_id.insert(id);
+            }
+            // Template instantiations only use their template arguments if the
+            // template definition uses the corresponding template parameter.
+            Some(&TypeKind::TemplateInstantiation(ref inst)) => {
+                if self.whitelisted_items.contains(&inst.template_definition()) {
+                    self.constrain_instantiation(id, &mut used_by_this_id, inst);
+                } else {
+                    self.constrain_instantiation_of_blacklisted_template(id,
+                                                                         &mut used_by_this_id,
+                                                                         inst);
+                }
+            }
+            // Otherwise, add the union of each of its referent item's template
+            // parameter usage.
+            _ => self.constrain_join(&mut used_by_this_id, item),
+        }
+
+        trace!("  finally, used set is {:?}", used_by_this_id);
+
+        let new_len = used_by_this_id.len();
+        assert!(new_len >= original_len,
+                "This is the property that ensures this function is monotone -- \
+                 if it doesn't hold, the analysis might never terminate!");
+
+        // Put the set back in the hash map and restore our invariant.
+        debug_assert!(self.used[&id].is_none());
+        self.used.insert(id, Some(used_by_this_id));
+        extra_assert!(self.used.values().all(|v| v.is_some()));
+
+        if new_len != original_len {
+            ConstrainResult::Changed
+        } else {
+            ConstrainResult::Same
+        }
+    }
+
+    fn each_depending_on<F>(&self, item: ItemId, mut f: F)
+        where F: FnMut(ItemId),
+    {
+        if let Some(edges) = self.dependencies.get(&item) {
+            for item in edges {
+                trace!("enqueue {:?} into worklist", item);
+                f(*item);
+            }
+        }
+    }
+}
+
+impl<'ctx, 'gen> From<UsedTemplateParameters<'ctx, 'gen>>
+    for HashMap<ItemId, ItemSet> {
+    fn from(used_templ_params: UsedTemplateParameters<'ctx, 'gen>) -> Self {
+        used_templ_params.used
+            .into_iter()
+            .map(|(k, v)| (k, v.unwrap()))
+            .collect()
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/bindgen/src/ir/comment.rs
@@ -0,0 +1,118 @@
+//! Utilities for manipulating C/C++ comments.
+
+use std::iter;
+
+/// The type of a comment.
+#[derive(Debug, PartialEq, Eq)]
+enum Kind {
+    /// A `///` comment, or something of the like.
+    /// All lines in a comment should start with the same symbol.
+    SingleLines,
+    /// A `/**` comment, where each other line can start with `*` and the
+    /// entire block ends with `*/`.
+    MultiLine,
+}
+
+/// Preprocesses a C/C++ comment so that it is a valid Rust comment.
+pub fn preprocess(comment: &str, indent: usize) -> String {
+    match self::kind(&comment) {
+        Some(Kind::SingleLines) => preprocess_single_lines(comment, indent),
+        Some(Kind::MultiLine) => preprocess_multi_line(comment, indent),
+        None => comment.to_owned(),
+    }
+}
+
+/// Gets the kind of the doc comment, if it is one.
+fn kind(comment: &str) -> Option<Kind> {
+    if comment.starts_with("/*") {
+        Some(Kind::MultiLine)
+    } else if comment.starts_with("//") {
+        Some(Kind::SingleLines)
+    } else {
+        None
+    }
+}
+
+fn make_indent(indent: usize) -> String {
+    const RUST_INDENTATION: usize = 4;
+
+    iter::repeat(' ').take(indent * RUST_INDENTATION).collect()
+}
+
+/// Preprocesses mulitple single line comments.
+///
+/// Handles lines starting with both `//` and `///`.
+fn preprocess_single_lines(comment: &str, indent: usize) -> String {
+    debug_assert!(comment.starts_with("//"), "comment is not single line");
+
+    let indent = make_indent(indent);
+    let mut is_first = true;
+    let lines: Vec<_> = comment.lines()
+        .map(|l| l.trim_left_matches('/').trim())
+        .map(|l| {
+            let indent = if is_first { "" } else { &*indent };
+            is_first = false;
+            let maybe_space = if l.is_empty() { "" } else { " " };
+            format!("{}///{}{}", indent, maybe_space, l)
+        })
+        .collect();
+    lines.join("\n")
+}
+
+fn preprocess_multi_line(comment: &str, indent: usize) -> String {
+    let comment = comment.trim_left_matches('/')
+                         .trim_left_matches('*')
+                         .trim_left_matches('!')
+                         .trim_right_matches('/')
+                         .trim_right_matches('*')
+                         .trim();
+
+    let indent = make_indent(indent);
+    // Strip any potential `*` characters preceding each line.
+    let mut is_first = true;
+    let mut lines: Vec<_> = comment.lines()
+        .map(|line| line.trim().trim_left_matches('*').trim())
+        .skip_while(|line| line.is_empty()) // Skip the first empty lines.
+        .map(|line| {
+            let indent = if is_first { "" } else { &*indent };
+            is_first = false;
+            let maybe_space = if line.is_empty() { "" } else { " " };
+            format!("{}///{}{}", indent, maybe_space, line)
+        })
+        .collect();
+
+    // Remove the trailing line corresponding to the `*/`.
+    let last_line_is_empty = lines.last().map_or(false, |l| l.is_empty());
+
+    if last_line_is_empty {
+        lines.pop();
+    }
+
+    lines.join("\n")
+}
+
+#[cfg(test)]
+mod test {
+    use super::*;
+
+    #[test]
+    fn picks_up_single_and_multi_line_doc_comments() {
+        assert_eq!(kind("/// hello"), Some(Kind::SingleLines));
+        assert_eq!(kind("/** world */"), Some(Kind::MultiLine));
+    }
+
+    #[test]
+    fn processes_single_lines_correctly() {
+        assert_eq!(preprocess("/// hello", 0), "/// hello");
+        assert_eq!(preprocess("// hello", 0), "/// hello");
+    }
+
+    #[test]
+    fn processes_multi_lines_correctly() {
+        assert_eq!(preprocess("/** hello \n * world \n * foo \n */", 0),
+                   "/// hello\n/// world\n/// foo");
+
+        assert_eq!(preprocess("/**\nhello\n*world\n*foo\n*/", 0),
+                   "/// hello\n/// world\n/// foo");
+    }
+}
--- a/third_party/rust/bindgen/src/ir/comp.rs
+++ b/third_party/rust/bindgen/src/ir/comp.rs
@@ -1,17 +1,18 @@
 //! 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::derive::{CanDeriveCopy, CanDeriveDefault};
 use super::dot::DotAttributes;
-use super::item::Item;
+use super::item::{IsOpaque, Item};
 use super::layout::Layout;
 use super::traversal::{EdgeKind, Trace, Tracer};
+use super::ty::RUST_DERIVE_IN_ARRAY_LIMIT;
 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;
@@ -696,30 +697,17 @@ impl FieldMethods for FieldData {
         &self.annotations
     }
 
     fn offset(&self) -> Option<usize> {
         self.offset
     }
 }
 
-impl CanDeriveDebug for Field {
-    type Extra = ();
-
-    fn can_derive_debug(&self, ctx: &BindgenContext, _: ()) -> bool {
-        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 {
+impl<'a> CanDeriveDefault<'a> for Field {
     type Extra = ();
 
     fn can_derive_default(&self, ctx: &BindgenContext, _: ()) -> bool {
         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, ())
             }),
@@ -827,17 +815,17 @@ pub struct CompInfo {
     /// static Foo::Bar const = {3};
     inner_types: Vec<ItemId>,
 
     /// Set of static constants declared inside this class.
     inner_vars: Vec<ItemId>,
 
     /// Whether this type should generate an vtable (TODO: Should be able to
     /// look at the virtual methods and ditch this field).
-    has_vtable: bool,
+    has_own_virtual_method: bool,
 
     /// Whether this type has destructor.
     has_destructor: bool,
 
     /// Whether this type has a base type with more than one member.
     ///
     /// TODO: We should be able to compute this.
     has_nonempty_base: bool,
@@ -852,20 +840,16 @@ pub struct CompInfo {
     /// Used to know if we've found an opaque attribute that could cause us to
     /// generate a type with invalid layout. This is explicitly used to avoid us
     /// generating bad alignments when parsing types like max_align_t.
     ///
     /// It's not clear what the behavior should be here, if generating the item
     /// and pray, or behave as an opaque type.
     found_unknown_attr: bool,
 
-    /// Used to detect if we've run in a can_derive_debug cycle while cycling
-    /// around the template arguments.
-    detect_derive_debug_cycle: Cell<bool>,
-
     /// Used to detect if we've run in a can_derive_default cycle while cycling
     /// around the template arguments.
     detect_derive_default_cycle: Cell<bool>,
 
     /// Used to detect if we've run in a has_destructor cycle while cycling
     /// around the template arguments.
     detect_has_destructor_cycle: Cell<bool>,
 
@@ -882,34 +866,33 @@ impl CompInfo {
             fields: CompFields::default(),
             template_params: vec![],
             methods: vec![],
             constructors: vec![],
             destructor: None,
             base_members: vec![],
             inner_types: vec![],
             inner_vars: vec![],
-            has_vtable: false,
+            has_own_virtual_method: false,
             has_destructor: false,
             has_nonempty_base: false,
             has_non_type_template_params: false,
             packed: false,
             found_unknown_attr: false,
-            detect_derive_debug_cycle: Cell::new(false),
             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() &&
+    pub fn is_unsized(&self, ctx: &BindgenContext, itemid: &ItemId) -> bool {
+        !ctx.lookup_item_id_has_vtable(itemid) && self.fields().is_empty() &&
         self.base_members.iter().all(|base| {
-            ctx.resolve_type(base.ty).canonical_type(ctx).is_unsized(ctx)
+            ctx.resolve_type(base.ty).canonical_type(ctx).is_unsized(ctx, &base.ty)
         })
     }
 
     /// Does this compound type have a destructor?
     pub fn has_destructor(&self, ctx: &BindgenContext) -> bool {
         if self.detect_has_destructor_cycle.get() {
             warn!("Cycle detected looking for destructors");
             // Assume no destructor, since we don't have an explicit one.
@@ -977,23 +960,20 @@ impl CompInfo {
     }
 
     /// 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
     }
 
-    /// Does this type have a virtual table?
-    pub fn has_vtable(&self, ctx: &BindgenContext) -> bool {
-        self.has_vtable ||
-        self.base_members().iter().any(|base| {
-            ctx.resolve_type(base.ty)
-                .has_vtable(ctx)
-        })
+    /// Do we see a virtual function during parsing?
+    /// Get the has_own_virtual_method boolean.
+    pub fn has_own_virtual_method(&self) -> bool {
+        return self.has_own_virtual_method;
     }
 
     /// Get this type's set of methods.
     pub fn methods(&self) -> &[Method] {
         &self.methods
     }
 
     /// Get this type's set of constructors.
@@ -1149,17 +1129,17 @@ impl CompInfo {
                     //
                     // Also, clang seems to scope struct definitions inside
                     // unions, and other named struct definitions inside other
                     // structs to the whole translation unit.
                     //
                     // Let's just assume that if the cursor we've found is a
                     // definition, it's a valid inner type.
                     //
-                    // [1]: https://github.com/servo/rust-bindgen/issues/482
+                    // [1]: https://github.com/rust-lang-nursery/rust-bindgen/issues/482
                     let is_inner_struct = cur.semantic_parent() == cursor ||
                                           cur.is_definition();
                     if !is_inner_struct {
                         return CXChildVisit_Continue;
                     }
 
                     let inner = Item::parse(cur, Some(potential_id), ctx)
                         .expect("Inner ClassDecl");
@@ -1182,17 +1162,17 @@ impl CompInfo {
                 CXCursor_TemplateTypeParameter => {
                     let param = Item::named_type(None, cur, ctx)
                         .expect("Item::named_type should't fail when pointing \
                                  at a TemplateTypeParameter");
                     ci.template_params.push(param);
                 }
                 CXCursor_CXXBaseSpecifier => {
                     let is_virtual_base = cur.is_virtual_base();
-                    ci.has_vtable |= is_virtual_base;
+                    ci.has_own_virtual_method |= is_virtual_base;
 
                     let kind = if is_virtual_base {
                         BaseKind::Virtual
                     } else {
                         BaseKind::Normal
                     };
 
                     let type_id =
@@ -1205,17 +1185,17 @@ impl CompInfo {
                 CXCursor_Constructor |
                 CXCursor_Destructor |
                 CXCursor_CXXMethod => {
                     let is_virtual = cur.method_is_virtual();
                     let is_static = cur.method_is_static();
                     debug_assert!(!(is_static && is_virtual), "How?");
 
                     ci.has_destructor |= cur.kind() == CXCursor_Destructor;
-                    ci.has_vtable |= is_virtual;
+                    ci.has_own_virtual_method |= is_virtual;
 
                     // This used to not be here, but then I tried generating
                     // stylo bindings with this (without path filters), and
                     // cried a lot with a method in gfx/Point.h
                     // (ToUnknownPoint), that somehow was causing the same type
                     // to be inserted in the map two times.
                     //
                     // I couldn't make a reduced test case, but anyway...
@@ -1348,29 +1328,29 @@ impl CompInfo {
 
     /// Is this compound type packed?
     pub fn packed(&self) -> bool {
         self.packed
     }
 
     /// Returns whether this type needs an explicit vtable because it has
     /// virtual methods and none of its base classes has already a vtable.
-    pub fn needs_explicit_vtable(&self, ctx: &BindgenContext) -> bool {
-        self.has_vtable(ctx) &&
+    pub fn needs_explicit_vtable(&self, ctx: &BindgenContext, item: &Item) -> bool {
+        ctx.lookup_item_id_has_vtable(&item.id()) &&
         !self.base_members.iter().any(|base| {
             // NB: Ideally, we could rely in all these types being `comp`, and
             // life would be beautiful.
             //
             // Unfortunately, given the way we implement --match-pat, and also
             // that you can inherit from templated types, we need to handle
             // other cases here too.
             ctx.resolve_type(base.ty)
                 .canonical_type(ctx)
                 .as_comp()
-                .map_or(false, |ci| ci.has_vtable(ctx))
+                .map_or(false, |_| ctx.lookup_item_id_has_vtable(&base.ty))
         })
     }
 
     /// Returns true if compound type has been forward declared
     pub fn is_forward_declaration(&self) -> bool {
         self.is_forward_declaration
     }
 
@@ -1381,17 +1361,17 @@ impl CompInfo {
 }
 
 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 {
+        if self.has_own_virtual_method {
             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 {
@@ -1417,101 +1397,70 @@ impl DotAttributes for CompInfo {
             }
             writeln!(out, "</table></td></tr>")?;
         }
 
         Ok(())
     }
 }
 
+impl IsOpaque for CompInfo {
+    type Extra = ();
+
+    fn is_opaque(&self, _: &BindgenContext, _: &()) -> bool {
+        self.has_non_type_template_params
+    }
+}
+
 impl TemplateParameters for CompInfo {
     fn self_template_params(&self,
                             _ctx: &BindgenContext)
                             -> Option<Vec<ItemId>> {
         if self.template_params.is_empty() {
             None
         } else {
             Some(self.template_params.clone())
         }
     }
 }
 
-impl CanDeriveDebug for CompInfo {
-    type Extra = Option<Layout>;
-
-    fn can_derive_debug(&self,
-                        ctx: &BindgenContext,
-                        layout: Option<Layout>)
-                        -> bool {
-        if self.has_non_type_template_params() {
-            return layout.map_or(false, |l| l.opaque().can_derive_debug(ctx, ()));
-        }
-
-        // We can reach here recursively via template parameters of a member,
-        // for example.
-        if self.detect_derive_debug_cycle.get() {
-            warn!("Derive debug cycle detected!");
-            return true;
-        }
-
-        if self.kind == CompKind::Union {
-            if ctx.options().unstable_rust {
-                return false;
-            }
-
-            return layout.unwrap_or_else(Layout::zero)
-                .opaque()
-                .can_derive_debug(ctx, ());
-        }
-
-        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()
-                .iter()
-                .all(|f| f.can_derive_debug(ctx, ()))
-        };
-
-        self.detect_derive_debug_cycle.set(false);
-
-        can_derive_debug
-    }
-}
-
-impl CanDeriveDefault for CompInfo {
-    type Extra = Option<Layout>;
+impl<'a> CanDeriveDefault<'a> for CompInfo {
+    type Extra = (&'a Item, Option<Layout>);
 
     fn can_derive_default(&self,
                           ctx: &BindgenContext,
-                          layout: Option<Layout>)
+                          (item, layout): (&Item, Option<Layout>))
                           -> bool {
         // We can reach here recursively via template parameters of a member,
         // for example.
         if self.detect_derive_default_cycle.get() {
             warn!("Derive default cycle detected!");
             return true;
         }
 
+        if layout.map_or(false, |l| l.align > RUST_DERIVE_IN_ARRAY_LIMIT) {
+            return false;
+        }
+
         if self.kind == CompKind::Union {
             if ctx.options().unstable_rust {
                 return false;
             }
 
-            return layout.unwrap_or_else(Layout::zero)
-                .opaque()
-                .can_derive_default(ctx, ());
+            return layout.map_or(true, |l| l.opaque().can_derive_default(ctx, ()));
+        }
+
+        if self.has_non_type_template_params {
+            return layout.map_or(true, |l| l.opaque().can_derive_default(ctx, ()));
         }
 
         self.detect_derive_default_cycle.set(true);
 
-        let can_derive_default = !self.has_vtable(ctx) &&
-                                 !self.needs_explicit_vtable(ctx) &&
+        let can_derive_default = !ctx.lookup_item_id_has_vtable(&item.id()) &&
+                                 !self.needs_explicit_vtable(ctx, item) &&
                                  self.base_members
             .iter()
             .all(|base| base.ty.can_derive_default(ctx, ())) &&
                                  self.fields()
             .iter()
             .all(|f| f.can_derive_default(ctx, ()));
 
         self.detect_derive_default_cycle.set(false);
@@ -1523,17 +1472,17 @@ impl CanDeriveDefault for CompInfo {
 impl<'a> CanDeriveCopy<'a> for CompInfo {
     type Extra = (&'a Item, Option<Layout>);
 
     fn can_derive_copy(&self,
                        ctx: &BindgenContext,
                        (item, layout): (&Item, Option<Layout>))
                        -> bool {
         if self.has_non_type_template_params() {
-            return layout.map_or(false, |l| l.opaque().can_derive_copy(ctx, ()));
+            return layout.map_or(true, |l| l.opaque().can_derive_copy(ctx, ()));
         }
 
         // NOTE: Take into account that while unions in C and C++ are copied by
         // default, the may have an explicit destructor in C++, so we can't
         // defer this check just for the union case.
         if self.has_destructor(ctx) {
             return false;
         }
@@ -1577,34 +1526,37 @@ impl Trace for CompInfo {
         for p in params {
             tracer.visit_kind(p, EdgeKind::TemplateParameterDefinition);
         }
 
         for &ty in self.inner_types() {
             tracer.visit_kind(ty, EdgeKind::InnerType);
         }
 
-        // We unconditionally trace `CompInfo`'s template parameters and inner
-        // types for the the usage analysis. However, we don't want to continue
-        // tracing anything else, if this type is marked opaque.
-        if item.is_opaque(context) {
+        for &var in self.inner_vars() {
+            tracer.visit_kind(var, EdgeKind::InnerVar);
+        }
+
+        for method in self.methods() {
+            if method.is_destructor() {
+                tracer.visit_kind(method.signature, EdgeKind::Destructor);
+            } else {
+                tracer.visit_kind(method.signature, EdgeKind::Method);
+            }
+        }
+
+        for &ctor in self.constructors() {
+            tracer.visit_kind(ctor, EdgeKind::Constructor);
+        }
+
+        // Base members and fields are not generated for opaque types (but all
+        // of the above things are) so stop here.
+        if item.is_opaque(context, &()) {
             return;
         }
 
         for base in self.base_members() {
             tracer.visit_kind(base.ty, EdgeKind::BaseMember);
         }
 
         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);
-        }
-
-        for &ctor in self.constructors() {
-            tracer.visit_kind(ctor, EdgeKind::Constructor);
-        }
     }
 }
--- a/third_party/rust/bindgen/src/ir/context.rs
+++ b/third_party/rust/bindgen/src/ir/context.rs
@@ -1,28 +1,28 @@
 //! Common context that is passed around during parsing and codegen.
 
 use super::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault};
 use super::int::IntKind;
-use super::item::{Item, ItemCanonicalPath, ItemSet};
+use super::item::{IsOpaque, Item, ItemAncestors, ItemCanonicalPath, ItemSet};
 use super::item_kind::ItemKind;
 use super::module::{Module, ModuleKind};
-use super::named::{UsedTemplateParameters, analyze};
+use super::analysis::{analyze, UsedTemplateParameters, CannotDeriveDebug, HasVtableAnalysis};
 use super::template::{TemplateInstantiation, TemplateParameters};
 use super::traversal::{self, Edge, ItemTraversal};
 use super::ty::{FloatKind, Type, TypeKind};
 use BindgenOptions;
 use cexpr;
 use callbacks::ParseCallbacks;
 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::{HashMap, hash_map, HashSet};
 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;
 
@@ -35,24 +35,22 @@ pub struct ItemId(usize);
 impl ItemId {
     /// Get a numeric representation of this id.
     pub fn as_usize(&self) -> usize {
         self.0
     }
 }
 
 impl CanDeriveDebug for ItemId {
-    type Extra = ();
-
-    fn can_derive_debug(&self, ctx: &BindgenContext, _: ()) -> bool {
-        ctx.resolve_item(*self).can_derive_debug(ctx, ())
+    fn can_derive_debug(&self, ctx: &BindgenContext) -> bool {
+        ctx.options().derive_debug && ctx.lookup_item_id_can_derive_debug(*self)
     }
 }
 
-impl CanDeriveDefault for ItemId {
+impl<'a> CanDeriveDefault<'a> for ItemId {
     type Extra = ();
 
     fn can_derive_default(&self, ctx: &BindgenContext, _: ()) -> bool {
         ctx.resolve_item(*self).can_derive_default(ctx, ())
     }
 }
 
 impl<'a> CanDeriveCopy<'a> for ItemId {
@@ -152,77 +150,96 @@ pub struct BindgenContext<'ctx> {
     translation_unit: clang::TranslationUnit,
 
     /// The options given by the user via cli or other medium.
     options: BindgenOptions,
 
     /// Whether a bindgen complex was generated
     generated_bindegen_complex: Cell<bool>,
 
+    /// The set of `ItemId`s that are whitelisted. This the very first thing
+    /// computed after parsing our IR, and before running any of our analyses.
+    whitelisted: Option<ItemSet>,
+
+    /// The set of `ItemId`s that are whitelisted for code generation _and_ that
+    /// we should generate accounting for the codegen options.
+    ///
+    /// It's computed right after computing the whitelisted items.
+    codegen_items: Option<ItemSet>,
+
     /// 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>,
 
     /// Whether we need the mangling hack which removes the prefixing underscore.
     needs_mangling_hack: bool,
+
+    /// The set of (`ItemId`s of) types that can't derive debug.
+    ///
+    /// This is populated when we enter codegen by `compute_can_derive_debug`
+    /// and is always `None` before that and `Some` after.
+    cant_derive_debug: Option<HashSet<ItemId>>,
+
+    /// The set of (`ItemId's of`) types that has vtable.
+    ///
+    /// Populated when we enter codegen by `compute_has_vtable`; always `None`
+    /// before that and `Some` after.
+    have_vtable: Option<HashSet<ItemId>>,
 }
 
 /// A traversal of whitelisted items.
-pub struct WhitelistedItems<'ctx, 'gen>
+struct WhitelistedItemsTraversal<'ctx, 'gen>
     where 'gen: 'ctx
 {
     ctx: &'ctx BindgenContext<'gen>,
     traversal: ItemTraversal<'ctx,
                              'gen,
                              ItemSet,
                              Vec<ItemId>,
-                             fn(Edge) -> bool>,
+                             for<'a> fn(&'a BindgenContext, Edge) -> bool>,
 }
 
-impl<'ctx, 'gen> Iterator for WhitelistedItems<'ctx, 'gen>
+impl<'ctx, 'gen> Iterator for WhitelistedItemsTraversal<'ctx, 'gen>
     where 'gen: 'ctx
 {
     type Item = ItemId;
 
     fn next(&mut self) -> Option<ItemId> {
         loop {
             match self.traversal.next() {
                 None => return None,
                 Some(id) if self.ctx.resolve_item(id).is_hidden(self.ctx) => continue,
                 Some(id) => return Some(id),
             }
         }
     }
 }
 
-impl<'ctx, 'gen> WhitelistedItems<'ctx, 'gen>
+impl<'ctx, 'gen> WhitelistedItemsTraversal<'ctx, 'gen>
     where 'gen: 'ctx
 {
     /// Construct a new whitelisted items traversal.
     pub fn new<R>(ctx: &'ctx BindgenContext<'gen>,
-                  roots: R)
-                  -> WhitelistedItems<'ctx, 'gen>
+                  roots: R,
+                  predicate: for<'a> fn(&'a BindgenContext, Edge) -> bool)
+                  -> Self
         where R: IntoIterator<Item = ItemId>,
     {
-        let predicate = if ctx.options().whitelist_recursively {
-            traversal::all_edges
-        } else {
-            traversal::no_edges
-        };
-        WhitelistedItems {
+        WhitelistedItemsTraversal {
             ctx: ctx,
             traversal: ItemTraversal::new(ctx, roots, predicate)
         }
     }
 }
+
 impl<'ctx> BindgenContext<'ctx> {
     /// Construct the context for the given `options`.
     pub fn new(options: BindgenOptions) -> Self {
         use clang_sys;
 
         let index = clang::Index::new(false, true);
 
         let parse_options =
@@ -256,24 +273,25 @@ impl<'ctx> BindgenContext<'ctx> {
         }
 
         if effective_target.is_none() {
             const HOST_TARGET: &'static str =
                 include_str!(concat!(env!("OUT_DIR"), "/host-target.txt"));
             effective_target = Some(HOST_TARGET.to_owned());
         }
 
-        // Mac os and Win32 need __ for mangled symbols but rust will automatically
+        // Mac os, iOS and Win32 need __ for mangled symbols but rust will automatically
         // prepend the extra _.
         //
         // We need to make sure that we don't include __ because rust will turn into
         // ___.
         let effective_target = effective_target.unwrap();
         let needs_mangling_hack =
             effective_target.contains("darwin") ||
+            effective_target.contains("ios") ||
             effective_target == "i686-pc-win32";
 
         let root_module = Self::build_root_module(ItemId(0));
         let mut me = BindgenContext {
             items: Default::default(),
             types: Default::default(),
             named_types: Default::default(),
             modules: Default::default(),
@@ -285,19 +303,23 @@ impl<'ctx> BindgenContext<'ctx> {
             replacements: Default::default(),
             collected_typerefs: false,
             gen_ctx: None,
             span: DUMMY_SP,
             index: index,
             translation_unit: translation_unit,
             options: options,
             generated_bindegen_complex: Cell::new(false),
+            whitelisted: None,
+            codegen_items: None,
             used_template_parameters: None,
             need_bitfield_allocation: Default::default(),
             needs_mangling_hack: needs_mangling_hack,
+            cant_derive_debug: None,
+            have_vtable: None,
         };
 
         me.add_item(root_module, None, None);
 
         me
     }
 
     /// Get the stack of partially parsed types that we are in the middle of
@@ -334,33 +356,27 @@ impl<'ctx> BindgenContext<'ctx> {
                     declaration: Option<Cursor>,
                     location: Option<Cursor>) {
         debug!("BindgenContext::add_item({:?}, declaration: {:?}, loc: {:?}",
                item,
                declaration,
                location);
         debug_assert!(declaration.is_some() || !item.kind().is_type() ||
                       item.kind().expect_type().is_builtin_or_named() ||
-                      item.kind().expect_type().is_opaque(),
+                      item.kind().expect_type().is_opaque(self, &item),
                       "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 item.id() != self.root_module {
+            self.add_item_to_module(&item);
         }
 
         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(),
@@ -402,27 +418,61 @@ impl<'ctx> BindgenContext<'ctx> {
                 TypeKey::Declaration(declaration)
             };
 
             let old = self.types.insert(key, id);
             debug_assert_eq!(old, None);
         }
     }
 
+    /// Ensure that every item (other than the root module) is in a module's
+    /// children list. This is to make sure that every whitelisted item get's
+    /// codegen'd, even if its parent is not whitelisted. See issue #769 for
+    /// details.
+    fn add_item_to_module(&mut self, item: &Item) {
+        assert!(item.id() != self.root_module);
+        assert!(!self.items.contains_key(&item.id()));
+
+        if let Some(mut parent) = self.items.get_mut(&item.parent_id()) {
+            if let Some(mut module) = parent.as_module_mut() {
+                debug!("add_item_to_module: adding {:?} as child of parent module {:?}",
+                       item.id(),
+                       item.parent_id());
+
+                module.children_mut().insert(item.id());
+                return;
+            }
+        }
+
+        debug!("add_item_to_module: adding {:?} as child of current module {:?}",
+               item.id(),
+               self.current_module);
+
+        self.items
+            .get_mut(&self.current_module)
+            .expect("Should always have an item for self.current_module")
+            .as_module_mut()
+            .expect("self.current_module should always be a module")
+            .children_mut()
+            .insert(item.id());
+    }
+
     /// Add a new named template type parameter to this context's item set.
     pub fn add_named_type(&mut self, item: Item, definition: clang::Cursor) {
         debug!("BindgenContext::add_named_type: item = {:?}; definition = {:?}",
                item,
                definition);
 
         assert!(item.expect_type().is_named(),
                 "Should directly be a named type, not a resolved reference or anything");
         assert_eq!(definition.kind(),
                    clang_sys::CXCursor_TemplateTypeParameter);
 
+        self.add_item_to_module(&item);
+
         let id = item.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");
 
         let old_named_ty = self.named_types.insert(definition, id);
         assert!(old_named_ty.is_none(),
                 "should not have already associated a named type with this id");
@@ -615,51 +665,75 @@ impl<'ctx> BindgenContext<'ctx> {
 
             let new_parent = {
                 let mut item = self.items.get_mut(&id).unwrap();
                 *item.kind_mut().as_type_mut().unwrap().kind_mut() =
                     TypeKind::ResolvedTypeRef(replacement);
                 item.parent_id()
             };
 
-
-            // Reparent the item.
-            let old_parent = self.resolve_item(replacement).parent_id();
-
-            if new_parent == old_parent {
-                continue;
-            }
+            // Relocate the replacement item from where it was declared, to
+            // where the thing it is replacing was declared.
+            //
+            // First, we'll make sure that its parent id is correct.
 
-            if let Some(mut module) = self.items
-                .get_mut(&old_parent)
-                .unwrap()
-                .as_module_mut() {
-                // Deparent the replacement.
-                let position = module.children()
-                    .iter()
-                    .position(|id| *id == replacement)
-                    .unwrap();
-                module.children_mut().remove(position);
-            }
-
-            if let Some(mut module) = self.items
-                .get_mut(&new_parent)
-                .unwrap()
-                .as_module_mut() {
-                module.children_mut().push(replacement);
+            let old_parent = self.resolve_item(replacement).parent_id();
+            if new_parent == old_parent {
+                // Same parent and therefore also same containing
+                // module. Nothing to do here.
+                continue;
             }
 
             self.items
                 .get_mut(&replacement)
                 .unwrap()
                 .set_parent_for_replacement(new_parent);
+
+            // Second, make sure that it is in the correct module's children
+            // set.
+
+            let old_module = {
+                let immut_self = &*self;
+                old_parent.ancestors(immut_self)
+                    .chain(Some(immut_self.root_module))
+                    .find(|id| {
+                        let item = immut_self.resolve_item(*id);
+                        item.as_module().map_or(false, |m| m.children().contains(&replacement))
+                    })
+            };
+            let old_module = old_module.expect("Every replacement item should be in a module");
+
+            let new_module = {
+                let immut_self = &*self;
+                new_parent.ancestors(immut_self).find(|id| {
+                    immut_self.resolve_item(*id).is_module()
+                })
+            };
+            let new_module = new_module.unwrap_or(self.root_module);
+
+            if new_module == old_module {
+                // Already in the correct module.
+                continue;
+            }
+
             self.items
-                .get_mut(&id)
+                .get_mut(&old_module)
+                .unwrap()
+                .as_module_mut()
                 .unwrap()
-                .set_parent_for_replacement(old_parent);
+                .children_mut()
+                .remove(&replacement);
+
+            self.items
+                .get_mut(&new_module)
+                .unwrap()
+                .as_module_mut()
+                .unwrap()
+                .children_mut()
+                .insert(replacement);
         }
     }
 
     /// Enter the code generation phase, invoke the given callback `cb`, and
     /// leave the code generation phase.
     pub fn gen<F, Out>(&mut self, cb: F) -> Out
         where F: FnOnce(&Self) -> Out,
     {
@@ -692,17 +766,33 @@ impl<'ctx> BindgenContext<'ctx> {
         self.assert_no_dangling_references();
 
         if !self.collected_typerefs() {
             self.resolve_typerefs();
             self.compute_bitfield_units();
             self.process_replacements();
         }
 
+        // And assert once again, because resolving type refs and processing
+        // replacements both mutate the IR graph.
+        self.assert_no_dangling_references();
+
+        // Compute the whitelisted set after processing replacements and
+        // resolving type refs, as those are the final mutations of the IR
+        // graph, and their completion means that the IR graph is now frozen.
+        self.compute_whitelisted_and_codegen_items();
+
+        // Make sure to do this after processing replacements, since that messes
+        // with the parentage and module children, and we want to assert that it
+        // messes with them correctly.
+        self.assert_every_item_in_a_module();
+
+        self.compute_has_vtable();
         self.find_used_template_parameters();
+        self.compute_cant_derive_debug();
 
         let ret = cb(self);
         self.gen_ctx = None;
         ret
     }
 
     /// When the `testing_only_extra_assertions` feature is enabled, this
     /// function walks the IR graph and asserts that we do not have any edges
@@ -722,25 +812,77 @@ impl<'ctx> BindgenContext<'ctx> {
         assert!(self.current_module == self.root_module);
 
         let roots = self.items().map(|(&id, _)| id);
         traversal::AssertNoDanglingItemsTraversal::new(self,
                                                        roots,
                                                        traversal::all_edges)
     }
 
+    /// When the `testing_only_extra_assertions` feature is enabled, walk over
+    /// every item and ensure that it is in the children set of one of its
+    /// module ancestors.
+    fn assert_every_item_in_a_module(&self) {
+        if cfg!(feature = "testing_only_extra_assertions") {
+            assert!(self.in_codegen_phase());
+            assert!(self.current_module == self.root_module);
+
+            for (&id, _item) in self.items() {
+                if id == self.root_module {
+                    continue;
+                }
+
+                assert!(
+                    {
+                        let id = id.into_resolver()
+                            .through_type_refs()
+                            .through_type_aliases()
+                            .resolve(self)
+                            .id();
+                        id.ancestors(self)
+                            .chain(Some(self.root_module))
+                            .any(|ancestor| {
+                                debug!("Checking if {:?} is a child of {:?}", id, ancestor);
+                                self.resolve_item(ancestor)
+                                    .as_module()
+                                    .map_or(false, |m| m.children().contains(&id))
+                            })
+                    },
+                    "{:?} should be in some ancestor module's children set",
+                    id
+                );
+            }
+        }
+    }
+
+    /// Compute whether the type has vtable.
+    fn compute_has_vtable(&mut self) {
+        assert!(self.have_vtable.is_none());
+        self.have_vtable = Some(analyze::<HasVtableAnalysis>(self));
+    }
+
+    /// Look up whether the item with `id` has vtable or not.
+    pub fn lookup_item_id_has_vtable(&self, id: &ItemId) -> bool {
+        assert!(self.in_codegen_phase(),
+                "We only compute vtables when we enter codegen");
+
+        // Look up the computed value for whether the item with `id` has a
+        // vtable or not.
+        self.have_vtable.as_ref().unwrap().contains(id)
+    }
+
     fn find_used_template_parameters(&mut self) {
         if self.options.whitelist_recursively {
             let used_params = analyze::<UsedTemplateParameters>(self);
             self.used_template_parameters = Some(used_params);
         } else {
             // If you aren't recursively whitelisting, then we can't really make
             // any sense of template parameter usage, and you're on your own.
             let mut used_params = HashMap::new();
-            for id in self.whitelisted_items() {
+            for &id in self.whitelisted_items() {
                 used_params.entry(id)
                     .or_insert(id.self_template_params(self)
                         .map_or(Default::default(),
                                 |params| params.into_iter().collect()));
             }
             self.used_template_parameters = Some(used_params);
         }
     }
@@ -778,27 +920,43 @@ impl<'ctx> BindgenContext<'ctx> {
 
         self.used_template_parameters
             .as_ref()
             .expect("should have found template parameter usage if we're in codegen")
             .get(&item)
             .map_or(false, |items_used_params| items_used_params.contains(&template_param))
     }
 
+    /// Return `true` if `item` uses any unbound, generic template parameters,
+    /// `false` otherwise.
+    ///
+    /// Has the same restrictions that `uses_template_parameter` has.
+    pub fn uses_any_template_parameters(&self, item: ItemId) -> bool {
+        assert!(self.in_codegen_phase(),
+                "We only compute template parameter usage as we enter codegen");
+
+        self.used_template_parameters
+            .as_ref()
+            .expect("should have template parameter usage info in codegen phase")
+            .get(&item)
+            .map_or(false, |used| !used.is_empty())
+    }
+
     // This deserves a comment. Builtin types don't get a valid declaration, so
     // we can't add it to the cursor->type map.
     //
     // That being said, they're not generated anyway, and are few, so the
     // duplication and special-casing is fine.
     //
     // If at some point we care about the memory here, probably a map TypeKind
     // -> builtin type ItemId would be the best to improve that.
     fn add_builtin_item(&mut self, item: Item) {
         debug!("add_builtin_item: item = {:?}", item);
         debug_assert!(item.kind().is_type());
+        self.add_item_to_module(&item);
         let id = item.id();
         let old_item = self.items.insert(id, item);
         assert!(old_item.is_none(), "Inserted type twice?");
     }
 
     fn build_root_module(id: ItemId) -> Item {
         let module = Module::new(Some("root".into()), ModuleKind::Normal);
         Item::new(id, None, None, id, ItemKind::Module(module))
@@ -924,20 +1082,24 @@ impl<'ctx> BindgenContext<'ctx> {
     ///   T p;
     /// };
     ///
     /// template<typename U>
     /// class Foo {
     ///   Incomplete<U> bar;
     /// };
     /// ```
+    ///
+    /// Finally, template instantiations are always children of the current
+    /// module. They use their template's definition for their name, so the
+    /// parent is only useful for ensuring that their layout tests get
+    /// codegen'd.
     fn instantiate_template(&mut self,
                             with_id: ItemId,
                             template: ItemId,
-                            parent_id: ItemId,
                             ty: &clang::Type,
                             location: clang::Cursor)
                             -> Option<ItemId> {
         use clang_sys;
 
         let num_expected_args = match self.resolve_type(template)
             .num_self_template_params(self) {
             Some(n) => n,
@@ -1033,23 +1195,24 @@ impl<'ctx> BindgenContext<'ctx> {
                                                    .fallible_layout()
                                                    .ok(),
                                                sub_kind,
                                                false);
                         let sub_id = self.next_item_id();
                         let sub_item = Item::new(sub_id,
                                                  None,
                                                  None,
-                                                 template_decl_id,
+                                                 self.current_module,
                                                  ItemKind::Type(sub_ty));
 
                         // Bypass all the validations in add_item explicitly.
                         debug!("instantiate_template: inserting nested \
                                 instantiation item: {:?}",
                                sub_item);
+                        self.add_item_to_module(&sub_item);
                         debug_assert!(sub_id == sub_item.id());
                         self.items.insert(sub_id, sub_item);
                         args.push(sub_id);
                     }
                 }
                 _ => {
                     warn!("Found template arg cursor we can't handle: {:?}",
                           child);
@@ -1081,20 +1244,21 @@ impl<'ctx> BindgenContext<'ctx> {
             TemplateInstantiation::new(template, args));
         let name = ty.spelling();
         let name = if name.is_empty() { None } else { Some(name) };
         let ty = Type::new(name,
                            ty.fallible_layout().ok(),
                            type_kind,
                            ty.is_const());
         let item =
-            Item::new(with_id, None, None, parent_id, ItemKind::Type(ty));
+            Item::new(with_id, None, None, self.current_module, ItemKind::Type(ty));
 
         // Bypass all the validations in add_item explicitly.
         debug!("instantiate_template: inserting item: {:?}", item);
+        self.add_item_to_module(&item);
         debug_assert!(with_id == item.id());
         self.items.insert(with_id, item);
         Some(with_id)
     }
 
     /// If we have already resolved the type for the given type declaration,
     /// return its `ItemId`. Otherwise, return `None`.
     pub fn get_resolved_type(&self,
@@ -1138,21 +1302,16 @@ impl<'ctx> BindgenContext<'ctx> {
                 //     of it, or
                 //   * we have already parsed and resolved this type, and
                 //     there's nothing left to do.
                 if decl.cursor().is_template_like() &&
                    *ty != decl.cursor().cur_type() &&
                    location.is_some() {
                     let location = location.unwrap();
 
-                    // It is always safe to hang instantiations off of the root
-                    // module. They use their template definition for naming,
-                    // and don't need the parent for anything else.
-                    let parent_id = self.root_module();
-
                     // For specialized type aliases, there's no way to get the
                     // template parameters as of this writing (for a struct
                     // specialization we wouldn't be in this branch anyway).
                     //
                     // Explicitly return `None` if there aren't any
                     // unspecialized parameters (contains any `TypeRef`) so we
                     // resolve the canonical type if there is one and it's
                     // exposed.
@@ -1161,17 +1320,16 @@ impl<'ctx> BindgenContext<'ctx> {
                     if decl.cursor().kind() == CXCursor_TypeAliasTemplateDecl &&
                        !location.contains_cursor(CXCursor_TypeRef) &&
                        ty.canonical_type().is_valid_and_exposed() {
                         return None;
                     }
 
                     return self.instantiate_template(with_id,
                                                      id,
-                                                     parent_id,
                                                      ty,
                                                      location)
                         .or_else(|| Some(id));
                 }
 
                 return Some(self.build_ty_wrapper(with_id, id, parent_id, ty));
             }
         }
@@ -1250,17 +1408,23 @@ impl<'ctx> BindgenContext<'ctx> {
                     CXType_LongDouble => FloatKind::LongDouble,
                     _ => panic!("Non floating-type complex?"),
                 };
                 TypeKind::Complex(float_kind)
             }
             _ => return None,
         };
 
-        let spelling = ty.spelling();
+        let mut spelling = ty.spelling();
+        // avoid the allocation if possible
+        if spelling.contains(' ') {
+            // These names are used in generated test names,
+            // they should be valid identifiers
+            spelling = spelling.replace(' ', "_");
+        }
         let is_const = ty.is_const();
         let layout = ty.fallible_layout().ok();
         let ty = Type::new(Some(spelling), layout, type_kind, is_const);
         let id = self.next_item_id();
         let item =
             Item::new(id, None, None, self.root_module, ItemKind::Type(ty));
         self.add_builtin_item(item);
         Some(id)
@@ -1444,87 +1608,135 @@ impl<'ctx> BindgenContext<'ctx> {
 
         self.current_module = previous_id;
     }
 
     /// Iterate over all (explicitly or transitively) whitelisted items.
     ///
     /// If no items are explicitly whitelisted, then all items are considered
     /// whitelisted.
-    pub fn whitelisted_items<'me>(&'me self) -> WhitelistedItems<'me, 'ctx> {
+    pub fn whitelisted_items(&self) -> &ItemSet {
         assert!(self.in_codegen_phase());
         assert!(self.current_module == self.root_module);
 
-        let roots = self.items()
-            .filter(|&(_, item)| {
-                // If nothing is explicitly whitelisted, then everything is fair
-                // game.
-                if self.options().whitelisted_types.is_empty() &&
-                   self.options().whitelisted_functions.is_empty() &&
-                   self.options().whitelisted_vars.is_empty() {
-                    return true;
-                }
+        self.whitelisted.as_ref().unwrap()
+    }
+
+    /// Get a reference to the set of items we should generate.
+    pub fn codegen_items(&self) -> &ItemSet {
+        assert!(self.in_codegen_phase());
+        assert!(self.current_module == self.root_module);
+        self.codegen_items.as_ref().unwrap()
+    }
 
-                // If this is a type that explicitly replaces another, we assume
-                // you know what you're doing.
-                if item.annotations().use_instead_of().is_some() {
-                    return true;
-                }
+    /// Compute the whitelisted items set and populate `self.whitelisted`.
+    fn compute_whitelisted_and_codegen_items(&mut self) {
+        assert!(self.in_codegen_phase());
+        assert!(self.current_module == self.root_module);
+        assert!(self.whitelisted.is_none());
 
-                let name = item.canonical_path(self)[1..].join("::");
-                debug!("whitelisted_items: testing {:?}", name);
-                match *item.kind() {
-                    ItemKind::Module(..) => true,
-                    ItemKind::Function(_) => {
-                        self.options().whitelisted_functions.matches(&name)
-                    }
-                    ItemKind::Var(_) => {
-                        self.options().whitelisted_vars.matches(&name)
-                    }
-                    ItemKind::Type(ref ty) => {
-                        if self.options().whitelisted_types.matches(&name) {
+        let roots = {
+            let mut roots = self.items()
+                // Only consider roots that are enabled for codegen.
+                .filter(|&(_, item)| item.is_enabled_for_codegen(self))
+                .filter(|&(_, item)| {
+                    // If nothing is explicitly whitelisted, then everything is fair
+                    // game.
+                    if self.options().whitelisted_types.is_empty() &&
+                        self.options().whitelisted_functions.is_empty() &&
+                        self.options().whitelisted_vars.is_empty() {
                             return true;
                         }
 
-                        let parent = self.resolve_item(item.parent_id());
-                        if parent.is_module() {
-                            let mut prefix_path = parent.canonical_path(self);
+                    // If this is a type that explicitly replaces another, we assume
+                    // you know what you're doing.
+                    if item.annotations().use_instead_of().is_some() {
+                        return true;
+                    }
+
+                    let name = item.canonical_path(self)[1..].join("::");
+                    debug!("whitelisted_items: testing {:?}", name);
+                    match *item.kind() {
+                        ItemKind::Module(..) => true,
+                        ItemKind::Function(_) => {
+                            self.options().whitelisted_functions.matches(&name)
+                        }
+                        ItemKind::Var(_) => {
+                            self.options().whitelisted_vars.matches(&name)
+                        }
+                        ItemKind::Type(ref ty) => {
+                            if self.options().whitelisted_types.matches(&name) {
+                                return true;
+                            }
 
-                            // Unnamed top-level enums are special and we
-                            // whitelist them via the `whitelisted_vars` filter,
-                            // since they're effectively top-level constants,
-                            // and there's no way for them to be referenced
-                            // consistently.
-                            if let TypeKind::Enum(ref enum_) = *ty.kind() {
-                                if ty.name().is_none() &&
-                                   enum_.variants().iter().any(|variant| {
-                                    prefix_path.push(variant.name().into());
-                                    let name = prefix_path[1..].join("::");
-                                    prefix_path.pop().unwrap();
-                                    self.options()
-                                        .whitelisted_vars
-                                        .matches(&name)
-                                }) {
-                                    return true;
+                            let parent = self.resolve_item(item.parent_id());
+                            if parent.is_module() {
+                                let mut prefix_path = parent.canonical_path(self);
+
+                                // Unnamed top-level enums are special and we
+                                // whitelist them via the `whitelisted_vars` filter,
+                                // since they're effectively top-level constants,
+                                // and there's no way for them to be referenced
+                                // consistently.
+                                if let TypeKind::Enum(ref enum_) = *ty.kind() {
+                                    if ty.name().is_none() &&
+                                        enum_.variants().iter().any(|variant| {
+                                            prefix_path.push(variant.name().into());
+                                            let name = prefix_path[1..].join("::");
+                                            prefix_path.pop().unwrap();
+                                            self.options()
+                                                .whitelisted_vars
+                                                .matches(&name)
+                                        }) {
+                                            return true;
+                                        }
                                 }
                             }
+
+                            false
                         }
-
-                        false
                     }
-                }
-            })
-            .map(|(&id, _)| id);
+                })
+                .map(|(&id, _)| id)
+                .collect::<Vec<_>>();
+
+            // The reversal preserves the expected ordering of traversal,
+            // resulting in more stable-ish bindgen-generated names for
+            // anonymous types (like unions).
+            roots.reverse();
+            roots
+        };
+
+        let whitelisted_items_predicate =
+            if self.options().whitelist_recursively {
+                traversal::all_edges
+            } else {
+                traversal::no_edges
+            };
 
-        // The reversal preserves the expected ordering of traversal, resulting
-        // in more stable-ish bindgen-generated names for anonymous types (like
-        // unions).
-        let mut roots: Vec<_> = roots.collect();
-        roots.reverse();
-        WhitelistedItems::new(self, roots)
+        let whitelisted =
+            WhitelistedItemsTraversal::new(
+                self,
+                roots.clone(),
+                whitelisted_items_predicate,
+            ).collect::<ItemSet>();
+
+        let codegen_items =
+            if self.options().whitelist_recursively {
+                WhitelistedItemsTraversal::new(
+                    self,
+                    roots.clone(),
+                    traversal::codegen_edges,
+                ).collect::<ItemSet>()
+            } else {
+                whitelisted.clone()
+            };
+
+        self.whitelisted = Some(whitelisted);
+        self.codegen_items = Some(codegen_items);
     }
 
     /// Convenient method for getting the prefix to use for most traits in
     /// codegen depending on the `use_core` option.
     pub fn trait_prefix(&self) -> Ident {
         if self.options().use_core {
             self.rust_ident_raw("core")
         } else {
@@ -1536,16 +1748,33 @@ impl<'ctx> BindgenContext<'ctx> {
     pub fn generated_bindegen_complex(&self) {
         self.generated_bindegen_complex.set(true)
     }
 
     /// Whether we need to generate the binden complex type
     pub fn need_bindegen_complex_type(&self) -> bool {
         self.generated_bindegen_complex.get()
     }
+
+    /// Compute whether we can derive debug.
+    fn compute_cant_derive_debug(&mut self) {
+        assert!(self.cant_derive_debug.is_none());
+        self.cant_derive_debug = Some(analyze::<CannotDeriveDebug>(self));
+    }
+
+    /// Look up whether the item with `id` can
+    /// derive debug or not.
+    pub fn lookup_item_id_can_derive_debug(&self, id: ItemId) -> bool {
+        assert!(self.in_codegen_phase(),
+                "We only compute can_derive_debug when we enter codegen");
+
+        // Look up the computed value for whether the item with `id` can
+        // derive debug or not.
+        !self.cant_derive_debug.as_ref().unwrap().contains(&id)
+    }
 }
 
 /// A builder struct for configuring item resolution options.
 #[derive(Debug, Copy, Clone)]
 pub struct ItemResolver {
     id: ItemId,
     through_type_refs: bool,
     through_type_aliases: bool,
--- a/third_party/rust/bindgen/src/ir/derive.rs
+++ b/third_party/rust/bindgen/src/ir/derive.rs
@@ -5,24 +5,33 @@ use super::context::BindgenContext;
 /// A trait that encapsulates the logic for whether or not we can derive `Debug`
 /// for a given thing.
 ///
 /// This should ideally be a no-op that just returns `true`, but instead needs
 /// to be a recursive method that checks whether all the proper members can
 /// derive debug or not, because of the limit rust has on 32 items as max in the
 /// array.
 pub trait CanDeriveDebug {
-    /// Implementations can define this type to get access to any extra
-    /// information required to determine whether they can derive `Debug`. If
-    /// extra information is unneeded, then this should simply be the unit type.
+    /// Return `true` if `Debug` can be derived for this thing, `false`
+    /// otherwise.
+    fn can_derive_debug(&self, ctx: &BindgenContext) -> bool;
+}
+
+/// A trait that encapsulates the logic for whether or not we can derive `Debug`.
+/// The difference between this trait and the CanDeriveDebug is that the type
+/// implementing this trait cannot use recursion or lookup result from fix point
+/// analysis. It's a helper trait for fix point analysis.
+pub trait CanTriviallyDeriveDebug {
+
+    /// Serve the same purpose as the Extra in CanDeriveDebug.
     type Extra;
 
     /// Return `true` if `Debug` can be derived for this thing, `false`
     /// otherwise.
-    fn can_derive_debug(&self,
+    fn can_trivially_derive_debug(&self,
                         ctx: &BindgenContext,
                         extra: Self::Extra)
                         -> bool;
 }
 
 /// A trait that encapsulates the logic for whether or not we can derive `Copy`
 /// for a given thing.
 pub trait CanDeriveCopy<'a> {
@@ -68,17 +77,17 @@ pub trait CanDeriveCopy<'a> {
 
 /// A trait that encapsulates the logic for whether or not we can derive `Default`
 /// for a given thing.
 ///
 /// This should ideally be a no-op that just returns `true`, but instead needs
 /// to be a recursive method that checks whether all the proper members can
 /// derive default or not, because of the limit rust has on 32 items as max in the
 /// array.
-pub trait CanDeriveDefault {
+pub trait CanDeriveDefault<'a> {
     /// Implementations can define this type to get access to any extra
     /// information required to determine whether they can derive `Default`. If
     /// extra information is unneeded, then this should simply be the unit type.
     type Extra;
 
     /// Return `true` if `Default` can be derived for this thing, `false`
     /// otherwise.
     fn can_derive_default(&self,
--- a/third_party/rust/bindgen/src/ir/dot.rs
+++ b/third_party/rust/bindgen/src/ir/dot.rs
@@ -50,13 +50,22 @@ pub fn write_dot_file<P>(ctx: &BindgenCo
                 Err(e) => err = Some(Err(e)),
             }
         },
                    &());
 
         if let Some(err) = err {
             return err;
         }
+
+        if let Some(module) = item.as_module() {
+            for child in module.children() {
+                try!(writeln!(&mut dot_file,
+                              "{} -> {} [style=dotted]",
+                              item.id().as_usize(),
+                              child.as_usize()));
+            }
+        }
     }
 
     try!(writeln!(&mut dot_file, "}}"));
     Ok(())
 }
--- a/third_party/rust/bindgen/src/ir/enum_ty.rs
+++ b/third_party/rust/bindgen/src/ir/enum_ty.rs
@@ -1,20 +1,23 @@
 //! Intermediate representation for C/C++ enumerations.
 
 use super::context::{BindgenContext, ItemId};
 use super::item::Item;
 use super::ty::TypeKind;
 use clang;
 use ir::annotations::Annotations;
+use ir::item::ItemCanonicalName;
 use parse::{ClangItemParser, ParseError};
 
 /// An enum representing custom handling that can be given to a variant.
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub enum EnumVariantCustomBehavior {
+    /// This variant will be a module containing constants.
+    ModuleConstify,
     /// This variant will be constified, that is, forced to generate a constant.
     Constify,
     /// This variant will be hidden entirely from the resulting enum.
     Hide,
 }
 
 /// A C/C++ enumeration.
 #[derive(Debug)]
@@ -116,16 +119,28 @@ impl Enum {
                                                    val,
                                                    custom_behavior));
                 }
             }
             CXChildVisit_Continue
         });
         Ok(Enum::new(repr, variants))
     }
+
+    /// Whether the enum should be an constified enum module
+    pub fn is_constified_enum_module(&self, ctx: &BindgenContext, item: &Item) -> bool {
+        let name = item.canonical_name(ctx);
+        let enum_ty = item.expect_type();
+
+        ctx.options().constified_enum_modules.matches(&name) ||
+        (enum_ty.name().is_none() &&
+            self.variants()
+            .iter()
+            .any(|v| ctx.options().constified_enum_modules.matches(&v.name())))
+    }
 }
 
 /// A single enum variant, to be contained only in an enum.
 #[derive(Debug)]
 pub struct EnumVariant {
     /// The name of the variant.
     name: String,
 
--- a/third_party/rust/bindgen/src/ir/function.rs
+++ b/third_party/rust/bindgen/src/ir/function.rs
@@ -1,22 +1,52 @@
 //! Intermediate representation for C/C++ functions and methods.
 
+use super::comp::MethodKind;
 use super::context::{BindgenContext, ItemId};
 use super::dot::DotAttributes;
 use super::item::Item;
 use super::traversal::{EdgeKind, Trace, Tracer};
 use super::ty::TypeKind;
 use clang;
-use clang_sys::CXCallingConv;
-use ir::derive::CanDeriveDebug;
+use clang_sys::{self, CXCallingConv};
+use ir::derive::CanTriviallyDeriveDebug;
 use parse::{ClangItemParser, ClangSubItemParser, ParseError, ParseResult};
 use std::io;
 use syntax::abi;
 
+/// What kind of a function are we looking at?
+#[derive(Debug, Copy, Clone, PartialEq)]
+pub enum FunctionKind {
+    /// A plain, free function.
+    Function,
+    /// A method of some kind.
+    Method(MethodKind),
+}
+
+impl FunctionKind {
+    fn from_cursor(cursor: &clang::Cursor) -> Option<FunctionKind> {
+        Some(match cursor.kind() {
+            clang_sys::CXCursor_FunctionDecl => FunctionKind::Function,
+            clang_sys::CXCursor_Constructor => FunctionKind::Method(MethodKind::Constructor),
+            clang_sys::CXCursor_Destructor => FunctionKind::Method(MethodKind::Destructor),
+            clang_sys::CXCursor_CXXMethod => {
+                if cursor.method_is_virtual() {
+                    FunctionKind::Method(MethodKind::Virtual)
+                } else if cursor.method_is_static() {
+                    FunctionKind::Method(MethodKind::Static)
+                } else {
+                    FunctionKind::Method(MethodKind::Normal)
+                }
+            }
+            _ => return None,
+        })
+    }
+}
+
 /// A function declaration, with a signature, arguments, and argument names.
 ///
 /// The argument names vector must be the same length as the ones in the
 /// signature.
 #[derive(Debug)]
 pub struct Function {
     /// The name of this function.
     name: String,
@@ -24,30 +54,35 @@ pub struct Function {
     /// The mangled name, that is, the symbol.
     mangled_name: Option<String>,
 
     /// The id pointing to the current function signature.
     signature: ItemId,
 
     /// The doc comment on the function, if any.
     comment: Option<String>,
+
+    /// The kind of function this is.
+    kind: FunctionKind,
 }
 
 impl Function {
     /// Construct a new function.
     pub fn new(name: String,
                mangled_name: Option<String>,
                sig: ItemId,
-               comment: Option<String>)
+               comment: Option<String>,
+               kind: FunctionKind)
                -> Self {
         Function {
             name: name,
             mangled_name: mangled_name,
             signature: sig,
             comment: comment,
+            kind: kind,
         }
     }
 
     /// Get this function's name.
     pub fn name(&self) -> &str {
         &self.name
     }
 
@@ -55,26 +90,32 @@ impl Function {
     pub fn mangled_name(&self) -> Option<&str> {
         self.mangled_name.as_ref().map(|n| &**n)
     }
 
     /// Get this function's signature.
     pub fn signature(&self) -> ItemId {
         self.signature
     }
+
+    /// Get this function's kind.
+    pub fn kind(&self) -> FunctionKind {
+        self.kind
+    }
 }
 
 impl DotAttributes for Function {
     fn dot_attributes<W>(&self,
                          _ctx: &BindgenContext,
                          out: &mut W)
                          -> io::Result<()>
         where W: io::Write,
     {
         if let Some(ref mangled) = self.mangled_name {
+            let mangled: String = mangled.chars().flat_map(|c| c.escape_default()).collect();
             try!(writeln!(out,
                           "<tr><td>mangled name</td><td>{}</td></tr>",
                           mangled));
         }
 
         Ok(())
     }
 }
@@ -125,32 +166,39 @@ fn get_abi(cc: CXCallingConv) -> Abi {
         CXCallingConv_AAPCS => abi::Abi::Aapcs,
         CXCallingConv_X86_64Win64 => abi::Abi::Win64,
         other => return Abi::Unknown(other),
     })
 }
 
 fn mangling_hack_if_needed(ctx: &BindgenContext, symbol: &mut String) {
     if ctx.needs_mangling_hack() {
-        symbol.remove(0);
+        match symbol.chars().next().unwrap() {
+            // Stripping leading underscore for all names on Darwin and
+            // C linkage functions on Win32.
+            '_' => { symbol.remove(0); }
+            // Stop Rust from prepending underscore for variables on Win32.
+            '?' => { symbol.insert(0, '\x01'); }
+            _ => {}
+        }
     }
 }
 
 /// Get the mangled name for the cursor's referent.
 pub fn cursor_mangling(ctx: &BindgenContext,
                        cursor: &clang::Cursor)
                        -> Option<String> {
     use clang_sys;
     if !ctx.options().enable_mangling {
         return None;
     }
 
     // We early return here because libclang may crash in some case
     // if we pass in a variable inside a partial specialized template.
-    // See servo/rust-bindgen#67, and servo/rust-bindgen#462.
+    // See rust-lang-nursery/rust-bindgen#67, and rust-lang-nursery/rust-bindgen#462.
     if cursor.is_in_non_fully_specialized_template() {
         return None;
     }
 
     if let Ok(mut manglings) = cursor.cxx_manglings() {
         if let Some(mut m) = manglings.pop() {
             mangling_hack_if_needed(ctx, &mut m);
             return Some(m);
@@ -344,22 +392,20 @@ impl FunctionSig {
     }
 }
 
 impl ClangSubItemParser for Function {
     fn parse(cursor: clang::Cursor,
              context: &mut BindgenContext)
              -> Result<ParseResult<Self>, ParseError> {
         use clang_sys::*;
-        match cursor.kind() {
-            CXCursor_FunctionDecl |
-            CXCursor_Constructor |
-            CXCursor_Destructor |
-            CXCursor_CXXMethod => {}
-            _ => return Err(ParseError::Continue),
+
+        let kind = match FunctionKind::from_cursor(&cursor) {
+            None => return Err(ParseError::Continue),
+            Some(k) => k,
         };
 
         debug!("Function::parse({:?}, {:?})", cursor, cursor.cur_type());
 
         let visibility = cursor.visibility();
         if visibility != CXVisibility_Default {
             return Err(ParseError::Continue);
         }
@@ -402,17 +448,17 @@ impl ClangSubItemParser for Function {
 
         let mut mangled_name = cursor_mangling(context, &cursor);
         if mangled_name.as_ref() == Some(&name) {
             mangled_name = None;
         }
 
         let comment = cursor.raw_comment();
 
-        let function = Self::new(name, mangled_name, sig, comment);
+        let function = Self::new(name, mangled_name, sig, comment, kind);
         Ok(ParseResult::New(function, Some(cursor)))
     }
 }
 
 impl Trace for FunctionSig {
     type Extra = ();
 
     fn trace<T>(&self, _: &BindgenContext, tracer: &mut T, _: &())
@@ -423,25 +469,25 @@ impl Trace for FunctionSig {
         for &(_, ty) in self.argument_types() {
             tracer.visit_kind(ty, EdgeKind::FunctionParameter);
         }
     }
 }
 
 // Function pointers follow special rules, see:
 //
-// https://github.com/servo/rust-bindgen/issues/547,
+// https://github.com/rust-lang-nursery/rust-bindgen/issues/547,
 // https://github.com/rust-lang/rust/issues/38848,
 // and https://github.com/rust-lang/rust/issues/40158
 //
 // Note that copy is always derived, so we don't need to implement it.
-impl CanDeriveDebug for FunctionSig {
+impl CanTriviallyDeriveDebug for FunctionSig {
     type Extra = ();
 
-    fn can_derive_debug(&self, _ctx: &BindgenContext, _: ()) -> bool {
+    fn can_trivially_derive_debug(&self, _ctx: &BindgenContext, _: ()) -> bool {
         const RUST_DERIVE_FUNPTR_LIMIT: usize = 12;
         if self.argument_types.len() > RUST_DERIVE_FUNPTR_LIMIT {
             return false;
         }
 
         match self.abi {
             Abi::Known(abi::Abi::C) |
             Abi::Unknown(..) => true,
--- a/third_party/rust/bindgen/src/ir/item.rs
+++ b/third_party/rust/bindgen/src/ir/item.rs
@@ -1,21 +1,25 @@
 //! Bindgen's core intermediate representation type.
 
+use super::super::codegen::CONSTIFIED_ENUM_MODULE_REPR_NAME;
 use super::annotations::Annotations;
+use super::comment;
+use super::comp::MethodKind;
 use super::context::{BindgenContext, ItemId, PartialType};
 use super::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault};
 use super::dot::DotAttributes;
-use super::function::Function;
+use super::function::{Function, FunctionKind};
 use super::item_kind::ItemKind;
 use super::layout::Opaque;
 use super::module::Module;
 use super::template::{AsTemplateParam, TemplateParameters};
 use super::traversal::{EdgeKind, Trace, Tracer};
 use super::ty::{Type, TypeKind};
+use super::analysis::HasVtable;
 use clang;
 use clang_sys;
 use parse::{ClangItemParser, ClangSubItemParser, ParseError, ParseResult};
 use std::cell::{Cell, RefCell};
 use std::collections::BTreeSet;
 use std::fmt::Write;
 use std::io;
 use std::iter;
@@ -55,16 +59,27 @@ pub trait ItemCanonicalPath {
     fn namespace_aware_canonical_path(&self,
                                       ctx: &BindgenContext)
                                       -> Vec<String>;
 
     /// Get the canonical path for this item.
     fn canonical_path(&self, ctx: &BindgenContext) -> Vec<String>;
 }
 
+/// A trait for determining if some IR thing is opaque or not.
+pub trait IsOpaque {
+    /// Extra context the IR thing needs to determine if it is opaque or not.
+    type Extra;
+
+    /// Returns `true` if the thing is opaque, and `false` otherwise.
+    ///
+    /// May only be called when `ctx` is in the codegen phase.
+    fn is_opaque(&self, ctx: &BindgenContext, extra: &Self::Extra) -> bool;
+}
+
 /// A trait for iterating over an item and its parents and up its ancestor chain
 /// up to (but not including) the implicit root module.
 pub trait ItemAncestors {
     /// Get an iterable over this item's ancestors.
     fn ancestors<'a, 'b>(&self,
                          ctx: &'a BindgenContext<'b>)
                          -> ItemAncestorsIter<'a, 'b>;
 }
@@ -225,17 +240,17 @@ impl Trace for Item {
         // function correctly.
 
         match *self.kind() {
             ItemKind::Type(ref ty) => {
                 // There are some types, like resolved type references, where we
                 // don't want to stop collecting types even though they may be
                 // opaque.
                 if ty.should_be_traced_unconditionally() ||
-                   !self.is_opaque(ctx) {
+                   !self.is_opaque(ctx, &()) {
                     ty.trace(ctx, tracer, self);
                 }
             }
             ItemKind::Function(ref fun) => {
                 // Just the same way, it has not real meaning for a function to
                 // be opaque, so we trace across it.
                 tracer.visit(fun.signature());
             }
@@ -251,57 +266,34 @@ impl Trace for Item {
                 // TODO: make a new edge kind for module -> children edges and
                 // filter them during whitelisting traversals.
             }
         }
     }
 }
 
 impl CanDeriveDebug for Item {
-    type Extra = ();
-
-    fn can_derive_debug(&self, ctx: &BindgenContext, _: ()) -> bool {
-        if self.detect_derive_debug_cycle.get() {
-            return true;
-        }
-
-        self.detect_derive_debug_cycle.set(true);
-
-        let result = ctx.options().derive_debug &&
-                     match self.kind {
-            ItemKind::Type(ref ty) => {
-                if self.is_opaque(ctx) {
-                    ty.layout(ctx)
-                        .map_or(true, |l| l.opaque().can_derive_debug(ctx, ()))
-                } else {
-                    ty.can_derive_debug(ctx, ())
-                }
-            }
-            _ => false,
-        };
-
-        self.detect_derive_debug_cycle.set(false);
-
-        result
+    fn can_derive_debug(&self, ctx: &BindgenContext) -> bool {
+        ctx.options().derive_debug && ctx.lookup_item_id_can_derive_debug(self.id())
     }
 }
 
-impl CanDeriveDefault for Item {
+impl<'a> CanDeriveDefault<'a> for Item {
     type Extra = ();
 
     fn can_derive_default(&self, ctx: &BindgenContext, _: ()) -> bool {
         ctx.options().derive_default &&
         match self.kind {
             ItemKind::Type(ref ty) => {
-                if self.is_opaque(ctx) {
+                if self.is_opaque(ctx, &()) {
                     ty.layout(ctx)
                         .map_or(false,
                                 |l| l.opaque().can_derive_default(ctx, ()))
                 } else {
-                    ty.can_derive_default(ctx, ())
+                    ty.can_derive_default(ctx, self)
                 }
             }
             _ => false,
         }
     }
 }
 
 impl<'a> CanDeriveCopy<'a> for Item {
@@ -311,17 +303,17 @@ impl<'a> CanDeriveCopy<'a> for Item {
         if self.detect_derive_copy_cycle.get() {
             return true;
         }
 
         self.detect_derive_copy_cycle.set(true);
 
         let result = match self.kind {
             ItemKind::Type(ref ty) => {
-                if self.is_opaque(ctx) {
+                if self.is_opaque(ctx, &()) {
                     ty.layout(ctx)
                         .map_or(true, |l| l.opaque().can_derive_copy(ctx, ()))
                 } else {
                     ty.can_derive_copy(ctx, self)
                 }
             }
             _ => false,
         };
@@ -329,17 +321,17 @@ impl<'a> CanDeriveCopy<'a> for Item {
         self.detect_derive_copy_cycle.set(false);
 
         result
     }
 
     fn can_derive_copy_in_array(&self, ctx: &BindgenContext, _: ()) -> bool {
         match self.kind {
             ItemKind::Type(ref ty) => {
-                if self.is_opaque(ctx) {
+                if self.is_opaque(ctx, &()) {
                     ty.layout(ctx)
                         .map_or(true, |l| {
                             l.opaque().can_derive_copy_in_array(ctx, ())
                         })
                 } else {
                     ty.can_derive_copy_in_array(ctx, self)
                 }
             }
@@ -462,19 +454,45 @@ impl Item {
 
     /// Set this item's parent id.
     ///
     /// This is only used so replacements get generated in the proper module.
     pub fn set_parent_for_replacement(&mut self, id: ItemId) {
         self.parent_id = id;
     }
 
-    /// Get this `Item`'s comment, if it has any.
-    pub fn comment(&self) -> Option<&str> {
-        self.comment.as_ref().map(|c| &**c)
+    /// Returns the depth this item is indented to.
+    ///
+    /// FIXME(emilio): This may need fixes for the enums within modules stuff.
+    pub fn codegen_depth(&self, ctx: &BindgenContext) -> usize {
+        if !ctx.options().enable_cxx_namespaces {
+            return 0;
+        }
+
+        self.ancestors(ctx)
+            .filter(|id| {
+                ctx.resolve_item(*id).as_module().map_or(false, |module| {
+                    !module.is_inline() ||
+                        ctx.options().conservative_inline_namespaces
+                })
+            })
+            .count() + 1
+    }
+
+
+    /// Get this `Item`'s comment, if it has any, already preprocessed and with
+    /// the right indentation.
+    pub fn comment(&self, ctx: &BindgenContext) -> Option<String> {
+        if !ctx.options().generate_comments {
+            return None;
+        }
+
+        self.comment.as_ref().map(|comment| {
+            comment::preprocess(comment, self.codegen_depth(ctx))
+        })
     }
 
     /// What kind of item is this?
     pub fn kind(&self) -> &ItemKind {
         &self.kind
     }
 
     /// Get a mutable reference to this item's kind.
@@ -587,25 +605,16 @@ impl Item {
     /// This may be due to either annotations or to other kind of configuration.
     pub fn is_hidden(&self, ctx: &BindgenContext) -> bool {
         debug_assert!(ctx.in_codegen_phase(),
                       "You're not supposed to call this yet");
         self.annotations.hide() ||
         ctx.hidden_by_name(&self.canonical_path(ctx), self.id)
     }
 
-    /// Is this item opaque?
-    pub fn is_opaque(&self, ctx: &BindgenContext) -> bool {
-        debug_assert!(ctx.in_codegen_phase(),
-                      "You're not supposed to call this yet");
-        self.annotations.opaque() ||
-        self.as_type().map_or(false, |ty| ty.is_opaque()) ||
-        ctx.opaque_by_name(&self.canonical_path(ctx))
-    }
-
     /// Is this a reference to another type?
     pub fn is_type_ref(&self) -> bool {
         self.as_type().map_or(false, |ty| ty.is_type_ref())
     }
 
     /// Is this item a var type?
     pub fn is_var(&self) -> bool {
         match *self.kind() {
@@ -646,16 +655,43 @@ impl Item {
                         _ => return item.id(),
                     }
                 }
                 _ => return item.id(),
             }
         }
     }
 
+    /// Create a fully disambiguated name for an item, including template
+    /// parameters if it is a type
+    pub fn full_disambiguated_name(&self, ctx: &BindgenContext) -> String {
+        let mut s = String::new();
+        let level = 0;
+        self.push_disambiguated_name(ctx, &mut s, level);
+        s
+    }
+
+    /// Helper function for full_disambiguated_name
+    fn push_disambiguated_name(&self, ctx: &BindgenContext, to: &mut String, level: u8) {
+        to.push_str(&self.canonical_name(ctx));
+        if let ItemKind::Type(ref ty) = *self.kind() {
+            if let TypeKind::TemplateInstantiation(ref inst) = *ty.kind() {
+                to.push_str(&format!("_open{}_", level));
+                for arg in inst.template_arguments() {
+                    arg.into_resolver()
+                       .through_type_refs()
+                       .resolve(ctx)
+                       .push_disambiguated_name(ctx, to, level + 1);
+                    to.push_str("_");
+                }
+                to.push_str(&format!("close{}", level));
+            }
+        }
+    }
+
     /// Get this function item's name, or `None` if this item is not a function.
     fn func_name(&self) -> Option<&str> {
         match *self.kind() {
             ItemKind::Function(ref func) => Some(func.name()),
             _ => None,
         }
     }
 
@@ -760,19 +796,29 @@ impl Item {
             return base_name;
         }
 
         // Concatenate this item's ancestors' names together.
         let mut names: Vec<_> = target.parent_id()
             .ancestors(ctx)
             .filter(|id| *id != ctx.root_module())
             .take_while(|id| {
-                // Stop iterating ancestors once we reach a namespace.
+                // Stop iterating ancestors once we reach a non-inline namespace
+                // when opt.within_namespaces is set.
                 !opt.within_namespaces || !ctx.resolve_item(*id).is_module()
             })
+            .filter(|id| {
+                if !ctx.options().conservative_inline_namespaces {
+                    if let ItemKind::Module(ref module) = *ctx.resolve_item(*id).kind() {
+                        return !module.is_inline();
+                    }
+                }
+
+                true
+            })
             .map(|id| {
                 let item = ctx.resolve_item(id);
                 let target = ctx.resolve_item(item.name_target(ctx));
                 target.base_name(ctx)
             })
             .filter(|name| !name.is_empty())
             .collect();
 
@@ -820,16 +866,101 @@ impl Item {
     /// Get a mutable reference to this item's `Module`, or `None` if this is
     /// not a `Module` item.
     pub fn as_module_mut(&mut self) -> Option<&mut Module> {
         match self.kind {
             ItemKind::Module(ref mut module) => Some(module),
             _ => None,
         }
     }
+
+    /// Returns whether the item is a constified module enum
+    fn is_constified_enum_module(&self, ctx: &BindgenContext) -> bool {
+        // Do not jump through aliases, except for aliases that point to a type
+        // with the same name, since we dont generate coe for them.
+        let item = self.id.into_resolver().through_type_refs().resolve(ctx);
+        let type_ = match *item.kind() {
+            ItemKind::Type(ref type_) => type_,
+            _ => return false,
+        };
+
+        match *type_.kind() {
+            TypeKind::Enum(ref enum_) => {
+                enum_.is_constified_enum_module(ctx, self)
+            }
+            TypeKind::Alias(inner_id) => {
+                // TODO(emilio): Make this "hop through type aliases that aren't
+                // really generated" an option in `ItemResolver`?
+                let inner_item = ctx.resolve_item(inner_id);
+                let name = item.canonical_name(ctx);
+
+                if inner_item.canonical_name(ctx) == name {
+                    inner_item.is_constified_enum_module(ctx)
+                } else {
+                    false
+                }
+            }
+            _ => false,
+        }
+    }
+
+    /// Is this item of a kind that is enabled for code generation?
+    pub fn is_enabled_for_codegen(&self, ctx: &BindgenContext) -> bool {
+        let cc = &ctx.options().codegen_config;
+        match *self.kind() {
+            ItemKind::Module(..) => true,
+            ItemKind::Var(_) => cc.vars,
+            ItemKind::Type(_) => cc.types,
+            ItemKind::Function(ref f) => {
+                match f.kind() {
+                    FunctionKind::Function => cc.functions,
+                    FunctionKind::Method(MethodKind::Constructor) => cc.constructors,
+                    FunctionKind::Method(MethodKind::Destructor) |
+                    FunctionKind::Method(MethodKind::VirtualDestructor) => cc.destructors,
+                    FunctionKind::Method(MethodKind::Static) |
+                    FunctionKind::Method(MethodKind::Normal) |
+                    FunctionKind::Method(MethodKind::Virtual) => cc.methods,
+                }
+            }
+        }
+    }
+}
+
+impl IsOpaque for ItemId {
+    type Extra = ();
+
+    fn is_opaque(&self, ctx: &BindgenContext, _: &()) -> bool {
+        debug_assert!(ctx.in_codegen_phase(),
+                      "You're not supposed to call this yet");
+        ctx.resolve_item(*self).is_opaque(ctx, &())
+    }
+}
+
+impl IsOpaque for Item {
+    type Extra = ();
+
+    fn is_opaque(&self, ctx: &BindgenContext, _: &()) -> bool {
+        debug_assert!(ctx.in_codegen_phase(),
+                      "You're not supposed to call this yet");
+        self.annotations.opaque() ||
+            self.as_type().map_or(false, |ty| ty.is_opaque(ctx, self)) ||
+            ctx.opaque_by_name(&self.canonical_path(ctx))
+    }
+}
+
+impl HasVtable for ItemId {
+    fn has_vtable(&self, ctx: &BindgenContext) -> bool {
+        ctx.lookup_item_id_has_vtable(self)
+    }
+}
+
+impl HasVtable for Item {
+    fn has_vtable(&self, ctx: &BindgenContext) -> bool {
+        ctx.lookup_item_id_has_vtable(&self.id())
+    }
 }
 
 /// A set of items.
 pub type ItemSet = BTreeSet<ItemId>;
 
 impl DotAttributes for Item {
     fn dot_attributes<W>(&self,
                          ctx: &BindgenContext,
@@ -838,17 +969,17 @@ impl DotAttributes for Item {
         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) {
+        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 {
@@ -1438,24 +1569,35 @@ impl ItemCanonicalName for Item {
         return self.canonical_name_cache.borrow().as_ref().unwrap().clone();
     }
 }
 
 impl ItemCanonicalPath for Item {
     fn namespace_aware_canonical_path(&self,
                                       ctx: &BindgenContext)
                                       -> Vec<String> {
-        let path = self.canonical_path(ctx);
-        if ctx.options().enable_cxx_namespaces {
-            return path;
+        let mut path = self.canonical_path(ctx);
+
+        // ASSUMPTION: (disable_name_namespacing && cxx_namespaces)
+        // is equivalent to
+        // disable_name_namespacing
+        if ctx.options().disable_name_namespacing {
+            // Only keep the last item in path
+            let split_idx = path.len() - 1;
+            path = path.split_off(split_idx);
+        } else if !ctx.options().enable_cxx_namespaces {
+            // Ignore first item "root"
+            path = vec![path[1..].join("_")];
         }
-        if ctx.options().disable_name_namespacing {
-            return vec![path.last().unwrap().clone()];
+
+        if self.is_constified_enum_module(ctx) {
+            path.push(CONSTIFIED_ENUM_MODULE_REPR_NAME.into());
         }
-        return vec![path[1..].join("_")];
+
+        return path;
     }
 
     fn canonical_path(&self, ctx: &BindgenContext) -> Vec<String> {
         if let Some(path) = self.annotations().use_instead_of() {
             let mut ret =
                 vec![ctx.resolve_item(ctx.root_module()).name(ctx).get()];
             ret.extend_from_slice(path);
             return ret;
--- a/third_party/rust/bindgen/src/ir/layout.rs
+++ b/third_party/rust/bindgen/src/ir/layout.rs
@@ -1,12 +1,12 @@
 //! Intermediate representation for the physical layout of some type.
 
 use super::context::BindgenContext;
-use super::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault};
+use super::derive::{CanDeriveCopy, CanTriviallyDeriveDebug, CanDeriveDefault};
 use super::ty::{RUST_DERIVE_IN_ARRAY_LIMIT, Type, TypeKind};
 use clang;
 use std::{cmp, mem};
 
 /// A type that represents the struct layout of a type.
 #[derive(Debug, Clone, Copy, PartialEq)]
 pub struct Layout {
     /// The size (in bytes) of this layout.
@@ -97,26 +97,26 @@ impl Opaque {
         if self.known_rust_type_for_array().is_some() {
             Some(self.0.size / cmp::max(self.0.align, 1))
         } else {
             None
         }
     }
 }
 
-impl CanDeriveDebug for Opaque {
+impl CanTriviallyDeriveDebug for Opaque {
     type Extra = ();
 
-    fn can_derive_debug(&self, _: &BindgenContext, _: ()) -> bool {
+    fn can_trivially_derive_debug(&self, _: &BindgenContext, _: ()) -> bool {
         self.array_size()
             .map_or(false, |size| size <= RUST_DERIVE_IN_ARRAY_LIMIT)
     }
 }
 
-impl CanDeriveDefault for Opaque {
+impl<'a> CanDeriveDefault<'a> for Opaque {
     type Extra = ();
 
     fn can_derive_default(&self, _: &BindgenContext, _: ()) -> bool {
         self.array_size()
             .map_or(false, |size| size <= RUST_DERIVE_IN_ARRAY_LIMIT)
     }
 }
 
--- a/third_party/rust/bindgen/src/ir/mod.rs
+++ b/third_party/rust/bindgen/src/ir/mod.rs
@@ -1,23 +1,24 @@
 //! The ir module defines bindgen's intermediate representation.
 //!
 //! Parsing C/C++ generates the IR, while code generation outputs Rust code from
 //! the IR.
 
 pub mod annotations;
+pub mod analysis;
 pub mod comp;
+pub mod comment;
 pub mod context;
 pub mod derive;
 pub mod dot;
 pub mod enum_ty;
 pub mod function;
 pub mod int;
 pub mod item;
 pub mod item_kind;
 pub mod layout;
 pub mod module;
-pub mod named;
 pub mod template;
 pub mod traversal;
 pub mod ty;
 pub mod var;
 pub mod objc;
--- a/third_party/rust/bindgen/src/ir/module.rs
+++ b/third_party/rust/bindgen/src/ir/module.rs
@@ -1,12 +1,13 @@
 //! Intermediate representation for modules (AKA C++ namespaces).
 
-use super::context::{BindgenContext, ItemId};
+use super::context::BindgenContext;
 use super::dot::DotAttributes;
+use super::item::ItemSet;
 use clang;
 use parse::{ClangSubItemParser, ParseError, ParseResult};
 use parse_one;
 use std::io;
 
 /// Whether this module is inline or not.
 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
 pub enum ModuleKind {
@@ -19,42 +20,42 @@ pub enum ModuleKind {
 /// A module, as in, a C++ namespace.
 #[derive(Clone, Debug)]
 pub struct Module {
     /// The name of the module, or none if it's anonymous.
     name: Option<String>,
     /// The kind of module this is.
     kind: ModuleKind,
     /// The children of this module, just here for convenience.
-    children_ids: Vec<ItemId>,
+    children: ItemSet,
 }
 
 impl Module {
     /// Construct a new `Module`.
     pub fn new(name: Option<String>, kind: ModuleKind) -> Self {
         Module {
             name: name,
             kind: kind,
-            children_ids: vec![],
+            children: ItemSet::new(),
         }
     }
 
     /// Get this module's name.
     pub fn name(&self) -> Option<&str> {
         self.name.as_ref().map(|n| &**n)
     }
 
     /// Get a mutable reference to this module's children.
-    pub fn children_mut(&mut self) -> &mut Vec<ItemId> {
-        &mut self.children_ids
+    pub fn children_mut(&mut self) -> &mut ItemSet {
+        &mut self.children
     }
 
     /// Get this module's children.
-    pub fn children(&self) -> &[ItemId] {
-        &self.children_ids
+    pub fn children(&self) -> &ItemSet {
+        &self.children
     }
 
     /// Whether this namespace is inline.
     pub fn is_inline(&self) -> bool {
         self.kind == ModuleKind::Inline
     }
 }
 
deleted file mode 100644
--- a/third_party/rust/bindgen/src/ir/named.rs
+++ /dev/null
@@ -1,832 +0,0 @@
-//! Discover which template type parameters are actually used.
-//!
-//! ### Why do we care?
-//!
-//! C++ allows ignoring template parameters, while Rust does not. Usually we can
-//! blindly stick a `PhantomData<T>` inside a generic Rust struct to make up for
-//! this. That doesn't work for templated type aliases, however:
-//!
-//! ```C++
-//! template <typename T>
-//! using Fml = int;
-//! ```
-//!
-//! If we generate the naive Rust code for this alias, we get:
-//!
-//! ```ignore
-//! pub type Fml<T> = ::std::os::raw::int;
-//! ```
-//!
-//! And this is rejected by `rustc` due to the unused type parameter.
-//!
-//! (Aside: in these simple cases, `libclang` will often just give us the
-//! aliased type directly, and we will never even know we were dealing with
-//! aliases, let alone templated aliases. It's the more convoluted scenarios
-//! where we get to have some fun...)
-//!
-//! For such problematic template aliases, we could generate a tuple whose
-//! second member is a `PhantomData<T>`. Or, if we wanted to go the extra mile,
-//! we could even generate some smarter wrapper that implements `Deref`,
-//! `DerefMut`, `From`, `Into`, `AsRef`, and `AsMut` to the actually aliased
-//! type. However, this is still lackluster:
-//!
-//! 1. Even with a billion conversion-trait implementations, using the generated
-//!    bindings is rather un-ergonomic.
-//! 2. With either of these solutions, we need to keep track of which aliases
-//!    we've transformed like this in order to generate correct uses of the
-//!    wrapped type.
-//!
-//! Given that we have to properly track which template parameters ended up used
-//! for (2), we might as well leverage that information to make ergonomic
-//! bindings that don't contain any unused type parameters at all, and
-//! completely avoid the pain of (1).
-//!
-//! ### How do we determine which template parameters are used?
-//!
-//! Determining which template parameters are actually used is a trickier
-//! problem than it might seem at a glance. On the one hand, trivial uses are
-//! easy to detect:
-//!
-//! ```C++
-//! template <typename T>
-//! class Foo {
-//!     T trivial_use_of_t;
-//! };
-//! ```
-//!
-//! It gets harder when determining if one template parameter is used depends on
-//! determining if another template parameter is used. In this example, whether
-//! `U` is used depends on whether `T` is used.
-//!
-//! ```C++
-//! template <typename T>
-//! class DoesntUseT {
-//!     int x;
-//! };
-//!
-//! template <typename U>
-//! class Fml {
-//!     DoesntUseT<U> lololol;
-//! };
-//! ```
-//!
-//! We can express the set of used template parameters as a constraint solving
-//! problem (where the set of template parameters used by a given IR item is the
-//! union of its sub-item's used template parameters) and iterate to a
-//! fixed-point.
-//!
-//! We use the "monotone framework" for this fix-point analysis where our
-//! lattice is the mapping from each IR item to the powerset of the template
-//! parameters that appear in the input C++ header, our join function is set
-//! union, and we use the `ir::traversal::Trace` trait to implement the
-//! work-list optimization so we don't have to revisit every node in the graph
-//! when for every iteration towards the fix-point.
-//!
-//! A lattice is a set with a partial ordering between elements, where there is
-//! a single least upper bound and a single greatest least bound for every
-//! subset. We are dealing with finite lattices, which means that it has a
-//! finite number of elements, and it follows that there exists a single top and
-//! a single bottom member of the lattice. For example, the power set of a
-//! finite set forms a finite lattice where partial ordering is defined by set
-//! inclusion, that is `a <= b` if `a` is a subset of `b`. Here is the finite
-//! lattice constructed from the set {0,1,2}:
-//!
-//! ```text
-//!                    .----- Top = {0,1,2} -----.
-//!                   /            |              \
-//!                  /             |               \
-//!                 /              |                \
-//!              {0,1} -------.  {0,2}  .--------- {1,2}
-//!                |           \ /   \ /             |
-//!                |            /     \              |
-//!                |           / \   / \             |
-//!               {0} --------'   {1}   `---------- {2}
-//!                 \              |                /
-//!                  \             |               /
-//!                   \            |              /
-//!                    `------ Bottom = {} ------'
-//! ```
-//!
-//! A monotone function `f` is a function where if `x <= y`, then it holds that
-//! `f(x) <= f(y)`. It should be clear that running a monotone function to a
-//! fix-point on a finite lattice will always terminate: `f` can only "move"
-//! along the lattice in a single direction, and therefore can only either find
-//! a fix-point in the middle of the lattice or continue to the top or bottom
-//! depending if it is ascending or descending the lattice respectively.
-//!
-//! For our analysis, we are collecting the set of template parameters used by
-//! any given IR node. The set of template parameters appearing in the program
-//! is finite. Our lattice is their powerset. We start at the bottom element,
-//! the empty set. Our analysis only adds members to the set of used template
-//! parameters, never removes them, so it is monotone, and therefore iteration
-//! to a fix-point will terminate.
-//!
-//! For a deeper introduction to the general form of this kind of analysis, see
-//! [Static Program Analysis by Anders Møller and Michael I. Schwartzbach][spa].
-//!
-//! [spa]: https://cs.au.dk/~amoeller/spa/spa.pdf
-
-use super::context::{BindgenContext, ItemId};
-use super::item::{Item, ItemSet};
-use super::template::{TemplateInstantiation, TemplateParameters};
-use super::traversal::{EdgeKind, Trace};
-use super::ty::TypeKind;
-use std::collections::{HashMap, HashSet};
-use std::fmt;
-
-/// An analysis in the monotone framework.
-///
-/// Implementors of this trait must maintain the following two invariants:
-///
-/// 1. The concrete data must be a member of a finite-height lattice.
-/// 2. The concrete `constrain` method must be monotone: that is,
-///    if `x <= y`, then `constrain(x) <= constrain(y)`.
-///
-/// If these invariants do not hold, iteration to a fix-point might never
-/// complete.
-///
-/// For a simple example analysis, see the `ReachableFrom` type in the `tests`
-/// module below.
-pub trait MonotoneFramework: Sized + fmt::Debug {
-    /// The type of node in our dependency graph.
-    ///
-    /// This is just generic (and not `ItemId`) so that we can easily unit test
-    /// without constructing real `Item`s and their `ItemId`s.
-    type Node: Copy;
-
-    /// Any extra data that is needed during computation.
-    ///
-    /// Again, this is just generic (and not `&BindgenContext`) so that we can
-    /// easily unit test without constructing real `BindgenContext`s full of
-    /// real `Item`s and real `ItemId`s.
-    type Extra: Sized;
-
-    /// The final output of this analysis. Once we have reached a fix-point, we
-    /// convert `self` into this type, and return it as the final result of the
-    /// analysis.
-    type Output: From<Self> + fmt::Debug;
-
-    /// Construct a new instance of this analysis.
-    fn new(extra: Self::Extra) -> Self;
-
-    /// Get the initial set of nodes from which to start the analysis. Unless
-    /// you are sure of some domain-specific knowledge, this should be the
-    /// complete set of nodes.
-    fn initial_worklist(&self) -> Vec<Self::Node>;
-
-    /// Update the analysis for the given node.
-    ///
-    /// If this results in changing our internal state (ie, we discovered that
-    /// we have not reached a fix-point and iteration should continue), return
-    /// `true`. Otherwise, return `false`. When `constrain` returns false for
-    /// all nodes in the set, we have reached a fix-point and the analysis is
-    /// complete.
-    fn constrain(&mut self, node: Self::Node) -> bool;
-
-    /// For each node `d` that depends on the given `node`'s current answer when
-    /// running `constrain(d)`, call `f(d)`. This informs us which new nodes to
-    /// queue up in the worklist when `constrain(node)` reports updated
-    /// information.
-    fn each_depending_on<F>(&self, node: Self::Node, f: F)
-        where F: FnMut(Self::Node);
-}
-
-/// Run an analysis in the monotone framework.
-pub fn analyze<Analysis>(extra: Analysis::Extra) -> Analysis::Output
-    where Analysis: MonotoneFramework,
-{
-    let mut analysis = Analysis::new(extra);
-    let mut worklist = analysis.initial_worklist();
-
-    while let Some(node) = worklist.pop() {
-        if analysis.constrain(node) {
-            analysis.each_depending_on(node, |needs_work| {
-                worklist.push(needs_work);
-            });
-        }
-    }
-
-    analysis.into()
-}
-
-/// An analysis that finds for each IR item its set of template parameters that
-/// it uses.
-///
-/// We use the monotone constraint function `template_param_usage`, defined as
-/// follows:
-///
-/// * If `T` is a named template type parameter, it trivially uses itself:
-///
-/// ```ignore
-/// template_param_usage(T) = { T }
-/// ```
-///
-/// * If `inst` is a template instantiation, `inst.args` are the template
-///   instantiation's template arguments, `inst.def` is the template definition
-///   being instantiated, and `inst.def.params` is the template definition's
-///   template parameters, then the instantiation's usage is the union of each
-///   of its arguments' usages *if* the corresponding template parameter is in
-///   turn used by the template definition:
-///
-/// ```ignore
-/// template_param_usage(inst) = union(
-///     template_param_usage(inst.args[i])
-///         for i in 0..length(inst.args.length)
-///             if inst.def.params[i] in template_param_usage(inst.def)
-/// )
-/// ```
-///
-/// * Finally, for all other IR item kinds, we use our lattice's `join`
-/// operation: set union with each successor of the given item's template
-/// parameter usage:
-///
-/// ```ignore
-/// template_param_usage(v) =
-///     union(template_param_usage(w) for w in successors(v))
-/// ```
-///
-/// Note that we ignore certain edges in the graph, such as edges from a
-/// template declaration to its template parameters' definitions for this
-/// analysis. If we didn't, then we would mistakenly determine that ever
-/// template parameter is always used.
-///
-/// The final wrinkle is handling of blacklisted types. Normally, we say that
-/// the set of whitelisted items is the transitive closure of items explicitly
-/// called out for whitelisting, *without* any items explicitly called out as
-/// blacklisted. However, for the purposes of this analysis's correctness, we
-/// simplify and consider run the analysis on the full transitive closure of
-/// whitelisted items. We do, however, treat instantiations of blacklisted items
-/// specially; see `constrain_instantiation_of_blacklisted_template` and its
-/// documentation for details.
-#[derive(Debug, Clone)]
-pub struct UsedTemplateParameters<'ctx, 'gen>
-    where 'gen: 'ctx,
-{
-    ctx: &'ctx BindgenContext<'gen>,
-
-    // The Option is only there for temporary moves out of the hash map. See the
-    // comments in `UsedTemplateParameters::constrain` below.
-    used: HashMap<ItemId, Option<ItemSet>>,
-
-    dependencies: HashMap<ItemId, Vec<ItemId>>,
-
-    // The set of whitelisted items, without any blacklisted items reachable
-    // from the whitelisted items which would otherwise be considered
-    // whitelisted as well.
-    whitelisted_items: HashSet<ItemId>,
-}
-
-impl<'ctx, 'gen> UsedTemplateParameters<'ctx, 'gen> {
-    fn consider_edge(kind: EdgeKind) -> bool {
-        match kind {
-            // For each of these kinds of edges, if the referent uses a template
-            // parameter, then it should be considered that the origin of the
-            // edge also uses the template parameter.
-            EdgeKind::TemplateArgument |
-            EdgeKind::BaseMember |
-            EdgeKind::Field |
-            EdgeKind::Constructor |
-            EdgeKind::VarType |
-            EdgeKind::FunctionReturn |
-            EdgeKind::FunctionParameter |
-            EdgeKind::TypeReference => true,
-
-            // An inner var or type using a template parameter is orthogonal
-            // from whether we use it. See template-param-usage-{6,11}.hpp.
-            EdgeKind::InnerVar | EdgeKind::InnerType => false,
-
-            // We can't emit machine code for new monomorphizations of class
-            // templates' methods (and don't detect explicit instantiations) so
-            // we must ignore template parameters that are only used by
-            // methods. This doesn't apply to a function type's return or
-            // parameter types, however, because of type aliases of function
-            // pointers that use template parameters, eg
-            // tests/headers/struct_with_typedef_template_arg.hpp
-            EdgeKind::Method => false,
-
-            // If we considered these edges, we would end up mistakenly claiming
-            // that every template parameter always used.
-            EdgeKind::TemplateDeclaration |
-            EdgeKind::TemplateParameterDefinition => false,
-
-            // Since we have to be careful about which edges we consider for
-            // this analysis to be correct, we ignore generic edges. We also
-            // avoid a `_` wild card to force authors of new edge kinds to
-            // determine whether they need to be considered by this analysis.
-            EdgeKind::Generic => false,
-        }
-    }
-
-    fn take_this_id_usage_set(&mut self, this_id: ItemId) -> ItemSet {
-        self.used
-            .get_mut(&this_id)
-            .expect("Should have a set of used template params for every item \
-                     id")
-            .take()
-            .expect("Should maintain the invariant that all used template param \
-                     sets are `Some` upon entry of `constrain`")
-    }
-
-    /// We say that blacklisted items use all of their template parameters. The
-    /// blacklisted type is most likely implemented explicitly by the user,
-    /// since it won't be in the generated bindings, and we don't know exactly
-    /// what they'll to with template parameters, but we can push the issue down
-    /// the line to them.
-    fn constrain_instantiation_of_blacklisted_template(&self,
-                                                       this_id: ItemId,
-                                                       used_by_this_id: &mut ItemSet,
-                                                       instantiation: &TemplateInstantiation) {
-        trace!("    instantiation of blacklisted template, uses all template \
-                arguments");
-
-        let args = instantiation.template_arguments()
-            .into_iter()
-            .map(|a| {
-                a.into_resolver()
-                    .through_type_refs()
-                    .through_type_aliases()
-                    .resolve(self.ctx)
-                    .id()
-            })
-            .filter(|a| *a != this_id)
-            .flat_map(|a| {
-                self.used.get(&a)
-                    .expect("Should have a used entry for the template arg")
-                    .as_ref()
-                    .expect("Because a != this_id, and all used template \
-                             param sets other than this_id's are `Some`, \
-                             a's used template param set should be `Some`")
-                    .iter()
-                    .cloned()
-            });
-
-        used_by_this_id.extend(args);
-    }
-
-    /// A template instantiation's concrete template argument is only used if
-    /// the template definition uses the corresponding template parameter.
-    fn constrain_instantiation(&self,
-                               this_id: ItemId,
-                               used_by_this_id: &mut ItemSet,
-                               instantiation: &TemplateInstantiation) {
-        trace!("    template instantiation");
-
-        let decl = self.ctx.resolve_type(instantiation.template_definition());
-        let args = instantiation.template_arguments();
-
-        let params = decl.self_template_params(self.ctx)
-            .unwrap_or(vec![]);
-
-        debug_assert!(this_id != instantiation.template_definition());
-        let used_by_def = self.used
-            .get(&instantiation.template_definition())
-            .expect("Should have a used entry for instantiation's template definition")
-            .as_ref()
-            .expect("And it should be Some because only this_id's set is None, and an \
-                     instantiation's template definition should never be the \
-                     instantiation itself");
-
-        for (arg, param) in args.iter().zip(params.iter()) {
-            trace!("      instantiation's argument {:?} is used if definition's \
-                    parameter {:?} is used",
-                   arg,
-                   param);
-
-            if used_by_def.contains(param) {
-                trace!("        param is used by template definition");
-
-                let arg = arg.into_resolver()
-                    .through_type_refs()
-                    .through_type_aliases()
-                    .resolve(self.ctx)
-                    .id();
-
-                if arg == this_id {
-                    continue;
-                }
-
-                let used_by_arg = self.used
-                    .get(&arg)
-                    .expect("Should have a used entry for the template arg")
-                    .as_ref()
-                    .expect("Because arg != this_id, and all used template \
-                             param sets other than this_id's are `Some`, \
-                             arg's used template param set should be \
-                             `Some`")
-                    .iter()
-                    .cloned();
-                used_by_this_id.extend(used_by_arg);
-            }
-        }
-    }
-
-    /// The join operation on our lattice: the set union of all of this id's
-    /// successors.
-    fn constrain_join(&self, used_by_this_id: &mut ItemSet, item: &Item) {
-        trace!("    other item: join with successors' usage");
-
-        item.trace(self.ctx, &mut |sub_id, edge_kind| {
-            // Ignore ourselves, since union with ourself is a
-            // no-op. Ignore edges that aren't relevant to the
-            // analysis.
-            if sub_id == item.id() || !Self::consider_edge(edge_kind) {
-                return;
-            }
-
-            let used_by_sub_id = self.used
-                .get(&sub_id)
-                .expect("Should have a used set for the sub_id successor")
-                .as_ref()
-                .expect("Because sub_id != id, and all used template \
-                         param sets other than id's are `Some`, \
-                         sub_id's used template param set should be \
-                         `Some`")
-                        .iter()
-                        .cloned();
-
-            trace!("      union with {:?}'s usage: {:?}",
-                   sub_id,
-                   used_by_sub_id.clone().collect::<Vec<_>>());
-
-            used_by_this_id.extend(used_by_sub_id);
-        }, &());
-    }
-}
-
-impl<'ctx, 'gen> MonotoneFramework for UsedTemplateParameters<'ctx, 'gen> {
-    type Node = ItemId;
-    type Extra = &'ctx BindgenContext<'gen>;
-    type Output = HashMap<ItemId, ItemSet>;
-
-    fn new(ctx: &'ctx BindgenContext<'gen>)
-           -> UsedTemplateParameters<'ctx, 'gen> {
-        let mut used = HashMap::new();
-        let mut dependencies = HashMap::new();
-        let whitelisted_items: HashSet<_> = ctx.whitelisted_items().collect();
-
-        let whitelisted_and_blacklisted_items: ItemSet = whitelisted_items.iter()
-            .cloned()
-            .flat_map(|i| {
-                let mut reachable = vec![i];
-                i.trace(ctx, &mut |s, _| {
-                    reachable.push(s);
-                }, &());
-                reachable
-            })
-            .collect();
-
-        for item in whitelisted_and_blacklisted_items {
-            dependencies.entry(item).or_insert(vec![]);
-            used.entry(item).or_insert(Some(ItemSet::new()));
-
-            {
-                // We reverse our natural IR graph edges to find dependencies
-                // between nodes.
-                item.trace(ctx, &mut |sub_item: ItemId, _| {
-                    used.entry(sub_item).or_insert(Some(ItemSet::new()));
-                    dependencies.entry(sub_item)
-                        .or_insert(vec![])
-                        .push(item);
-                }, &());
-            }
-
-            // Additionally, whether a template instantiation's template
-            // arguments are used depends on whether the template declaration's
-            // generic template parameters are used.
-            ctx.resolve_item(item)
-                .as_type()
-                .map(|ty| match ty.kind() {
-                    &TypeKind::TemplateInstantiation(ref inst) => {
-                        let decl = ctx.resolve_type(inst.template_definition());
-                        let args = inst.template_arguments();
-
-                        // Although template definitions should always have
-                        // template parameters, there is a single exception:
-                        // opaque templates. Hence the unwrap_or.
-                        let params = decl.self_template_params(ctx)
-                            .unwrap_or(vec![]);
-
-                        for (arg, param) in args.iter().zip(params.iter()) {
-                            let arg = arg.into_resolver()
-                                .through_type_aliases()
-                                .through_type_refs()
-                                .resolve(ctx)
-                                .id();
-
-                            let param = param.into_resolver()
-                                .through_type_aliases()
-                                .through_type_refs()
-                                .resolve(ctx)
-                                .id();
-
-                            used.entry(arg).or_insert(Some(ItemSet::new()));
-                            used.entry(param).or_insert(Some(ItemSet::new()));
-
-                            dependencies.entry(arg)
-                                .or_insert(vec![])
-                                .push(param);
-                        }
-                    }
-                    _ => {}
-                });
-        }
-
-        if cfg!(feature = "testing_only_extra_assertions") {
-            // Invariant: The `used` map has an entry for every whitelisted
-            // item, as well as all explicitly blacklisted items that are
-            // reachable from whitelisted items.
-            //
-            // Invariant: the `dependencies` map has an entry for every
-            // whitelisted item.
-            //
-            // (This is so that every item we call `constrain` on is guaranteed
-            // to have a set of template parameters, and we can allow
-            // blacklisted templates to use all of their parameters).
-            for item in whitelisted_items.iter() {
-                extra_assert!(used.contains_key(item));
-                extra_assert!(dependencies.contains_key(item));
-                item.trace(ctx, &mut |sub_item, _| {
-                    extra_assert!(used.contains_key(&sub_item));
-                    extra_assert!(dependencies.contains_key(&sub_item));
-                }, &())
-            }
-        }
-
-        UsedTemplateParameters {
-            ctx: ctx,
-            used: used,
-            dependencies: dependencies,
-            whitelisted_items: whitelisted_items,
-        }
-    }
-
-    fn initial_worklist(&self) -> Vec<ItemId> {
-        // The transitive closure of all whitelisted items, including explicitly
-        // blacklisted items.
-        self.ctx
-            .whitelisted_items()
-            .flat_map(|i| {
-                let mut reachable = vec![i];
-                i.trace(self.ctx, &mut |s, _| {
-                    reachable.push(s);
-                }, &());
-                reachable
-            })
-            .collect()
-    }
-
-    fn constrain(&mut self, id: ItemId) -> bool {
-        // Invariant: all hash map entries' values are `Some` upon entering and
-        // exiting this method.
-        extra_assert!(self.used.values().all(|v| v.is_some()));
-
-        // Take the set for this id out of the hash map while we mutate it based
-        // on other hash map entries. We *must* put it back into the hash map at
-        // the end of this method. This allows us to side-step HashMap's lack of
-        // an analog to slice::split_at_mut.
-        let mut used_by_this_id = self.take_this_id_usage_set(id);
-
-        trace!("constrain {:?}", id);
-        trace!("  initially, used set is {:?}", used_by_this_id);
-
-        let original_len = used_by_this_id.len();
-
-        let item = self.ctx.resolve_item(id);
-        let ty_kind = item.as_type().map(|ty| ty.kind());
-        match ty_kind {
-            // Named template type parameters trivially use themselves.
-            Some(&TypeKind::Named) => {
-                trace!("    named type, trivially uses itself");
-                used_by_this_id.insert(id);
-            }
-            // Template instantiations only use their template arguments if the
-            // template definition uses the corresponding template parameter.
-            Some(&TypeKind::TemplateInstantiation(ref inst)) => {
-                if self.whitelisted_items.contains(&inst.template_definition()) {
-                    self.constrain_instantiation(id, &mut used_by_this_id, inst);
-                } else {
-                    self.constrain_instantiation_of_blacklisted_template(id,
-                                                                         &mut used_by_this_id,
-                                                                         inst);
-                }
-            }
-            // Otherwise, add the union of each of its referent item's template
-            // parameter usage.
-            _ => self.constrain_join(&mut used_by_this_id, item),
-        }
-
-        trace!("  finally, used set is {:?}", used_by_this_id);
-
-        let new_len = used_by_this_id.len();
-        assert!(new_len >= original_len,
-                "This is the property that ensures this function is monotone -- \
-                 if it doesn't hold, the analysis might never terminate!");
-
-        // Put the set back in the hash map and restore our invariant.
-        debug_assert!(self.used[&id].is_none());
-        self.used.insert(id, Some(used_by_this_id));
-        extra_assert!(self.used.values().all(|v| v.is_some()));
-
-        new_len != original_len
-    }
-
-    fn each_depending_on<F>(&self, item: ItemId, mut f: F)
-        where F: FnMut(ItemId),
-    {
-        if let Some(edges) = self.dependencies.get(&item) {
-            for item in edges {
-                trace!("enqueue {:?} into worklist", item);
-                f(*item);
-            }
-        }
-    }
-}
-
-impl<'ctx, 'gen> From<UsedTemplateParameters<'ctx, 'gen>>
-    for HashMap<ItemId, ItemSet> {
-    fn from(used_templ_params: UsedTemplateParameters<'ctx, 'gen>) -> Self {
-        used_templ_params.used
-            .into_iter()
-            .map(|(k, v)| (k, v.unwrap()))
-            .collect()
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use std::collections::{HashMap, HashSet};
-
-    // Here we find the set of nodes that are reachable from any given
-    // node. This is a lattice mapping nodes to subsets of all nodes. Our join
-    // function is set union.
-    //
-    // This is our test graph:
-    //
-    //     +---+                    +---+
-    //     |   |                    |   |
-    //     | 1 |               .----| 2 |
-    //     |   |               |    |   |
-    //     +---+               |    +---+
-    //       |                 |      ^
-    //       |                 |      |
-    //       |      +---+      '------'
-    //       '----->|   |
-    //              | 3 |
-    //       .------|   |------.
-    //       |      +---+      |
-    //       |        ^        |
-    //       v        |        v
-    //     +---+      |      +---+    +---+
-    //     |   |      |      |   |    |   |
-    //     | 4 |      |      | 5 |--->| 6 |
-    //     |   |      |      |   |    |   |
-    //     +---+      |      +---+    +---+
-    //       |        |        |        |
-    //       |        |        |        v
-    //       |      +---+      |      +---+
-    //       |      |   |      |      |   |
-    //       '----->| 7 |<-----'      | 8 |
-    //              |   |             |   |
-    //              +---+             +---+
-    //
-    // And here is the mapping from a node to the set of nodes that are
-    // reachable from it within the test graph:
-    //
-    //     1: {3,4,5,6,7,8}
-    //     2: {2}
-    //     3: {3,4,5,6,7,8}
-    //     4: {3,4,5,6,7,8}
-    //     5: {3,4,5,6,7,8}
-    //     6: {8}
-    //     7: {3,4,5,6,7,8}
-    //     8: {}
-
-    #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
-    struct Node(usize);
-
-    #[derive(Clone, Debug, Default, PartialEq, Eq)]
-    struct Graph(HashMap<Node, Vec<Node>>);
-
-    impl Graph {
-        fn make_test_graph() -> Graph {
-            let mut g = Graph::default();
-            g.0.insert(Node(1), vec![Node(3)]);
-            g.0.insert(Node(2), vec![Node(2)]);
-            g.0.insert(Node(3), vec![Node(4), Node(5)]);
-            g.0.insert(Node(4), vec![Node(7)]);
-            g.0.insert(Node(5), vec![Node(6), Node(7)]);
-            g.0.insert(Node(6), vec![Node(8)]);
-            g.0.insert(Node(7), vec![Node(3)]);
-            g.0.insert(Node(8), vec![]);
-            g
-        }
-
-        fn reverse(&self) -> Graph {
-            let mut reversed = Graph::default();
-            for (node, edges) in self.0.iter() {
-                reversed.0.entry(*node).or_insert(vec![]);
-                for referent in edges.iter() {
-                    reversed.0.entry(*referent).or_insert(vec![]).push(*node);
-                }
-            }
-            reversed
-        }
-    }
-
-    #[derive(Clone, Debug, PartialEq, Eq)]
-    struct ReachableFrom<'a> {
-        reachable: HashMap<Node, HashSet<Node>>,
-        graph: &'a Graph,
-        reversed: Graph,
-    }
-
-    impl<'a> MonotoneFramework for ReachableFrom<'a> {
-        type Node = Node;
-        type Extra = &'a Graph;
-        type Output = HashMap<Node, HashSet<Node>>;
-
-        fn new(graph: &'a Graph) -> ReachableFrom {
-            let reversed = graph.reverse();
-            ReachableFrom {
-                reachable: Default::default(),
-                graph: graph,
-                reversed: reversed,
-            }
-        }
-
-        fn initial_worklist(&self) -> Vec<Node> {
-            self.graph.0.keys().cloned().collect()
-        }
-
-        fn constrain(&mut self, node: Node) -> bool {
-            // The set of nodes reachable from a node `x` is
-            //
-            //     reachable(x) = s_0 U s_1 U ... U reachable(s_0) U reachable(s_1) U ...
-            //
-            // where there exist edges from `x` to each of `s_0, s_1, ...`.
-            //
-            // Yes, what follows is a **terribly** inefficient set union
-            // implementation. Don't copy this code outside of this test!
-
-            let original_size =
-                self.reachable.entry(node).or_insert(HashSet::new()).len();
-
-            for sub_node in self.graph.0[&node].iter() {
-                self.reachable.get_mut(&node).unwrap().insert(*sub_node);
-
-                let sub_reachable = self.reachable
-                    .entry(*sub_node)
-                    .or_insert(HashSet::new())
-                    .clone();
-
-                for transitive in sub_reachable {
-                    self.reachable.get_mut(&node).unwrap().insert(transitive);
-                }
-            }
-
-            let new_size = self.reachable[&node].len();
-            original_size != new_size
-        }
-
-        fn each_depending_on<F>(&self, node: Node, mut f: F)
-            where F: FnMut(Node),
-        {
-            for dep in self.reversed.0[&node].iter() {
-                f(*dep);
-            }
-        }
-    }
-
-    impl<'a> From<ReachableFrom<'a>> for HashMap<Node, HashSet<Node>> {
-        fn from(reachable: ReachableFrom<'a>) -> Self {
-            reachable.reachable
-        }
-    }
-
-    #[test]
-    fn monotone() {
-        let g = Graph::make_test_graph();
-        let reachable = analyze::<ReachableFrom>(&g);
-        println!("reachable = {:#?}", reachable);
-
-        fn nodes<A>(nodes: A) -> HashSet<Node>
-            where A: AsRef<[usize]>,
-        {
-            nodes.as_ref().iter().cloned().map(Node).collect()
-        }
-
-        let mut expected = HashMap::new();
-        expected.insert(Node(1), nodes([3, 4, 5, 6, 7, 8]));
-        expected.insert(Node(2), nodes([2]));
-        expected.insert(Node(3), nodes([3, 4, 5, 6, 7, 8]));
-        expected.insert(Node(4), nodes([3, 4, 5, 6, 7, 8]));
-        expected.insert(Node(5), nodes([3, 4, 5, 6, 7, 8]));
-        expected.insert(Node(6), nodes([8]));
-        expected.insert(Node(7), nodes([3, 4, 5, 6, 7, 8]));
-        expected.insert(Node(8), nodes([]));
-        println!("expected = {:#?}", expected);
-
-        assert_eq!(reachable, expected);
-    }
-}
--- a/third_party/rust/bindgen/src/ir/template.rs
+++ b/third_party/rust/bindgen/src/ir/template.rs
@@ -23,19 +23,18 @@
 //! ```c++
 //! template<>
 //! class List<int> {
 //!     // Special layout for int lists...
 //! };
 //! ```
 
 use super::context::{BindgenContext, ItemId};
-use super::derive::{CanDeriveCopy, CanDeriveDebug};
-use super::item::{Item, ItemAncestors};
-use super::layout::Layout;
+use super::derive::{CanDeriveCopy};
+use super::item::{IsOpaque, Item, ItemAncestors, ItemCanonicalPath};
 use super::traversal::{EdgeKind, Trace, Tracer};
 use clang;
 use parse::ClangItemParser;
 
 /// Template declaration (and such declaration's template parameters) related
 /// methods.
 ///
 /// This trait's methods distinguish between `None` and `Some([])` for
@@ -288,67 +287,71 @@ impl TemplateInstantiation {
         };
 
         let template_definition =
             Item::from_ty_or_ref(definition.cur_type(), definition, None, ctx);
 
         Some(TemplateInstantiation::new(template_definition, template_args))
     }
 
-    /// Does this instantiation have a vtable?
-    pub fn has_vtable(&self, ctx: &BindgenContext) -> bool {
-        ctx.resolve_type(self.definition).has_vtable(ctx)
-    }
-
     /// Does this instantiation have a destructor?
     pub fn has_destructor(&self, ctx: &BindgenContext) -> bool {
         ctx.resolve_type(self.definition).has_destructor(ctx) ||
         self.args.iter().any(|arg| ctx.resolve_type(*arg).has_destructor(ctx))
     }
 }
 
+impl IsOpaque for TemplateInstantiation {
+    type Extra = Item;
+
+    /// Is this an opaque template instantiation?
+    fn is_opaque(&self, ctx: &BindgenContext, item: &Item) -> bool {
+        if self.template_definition().is_opaque(ctx, &()) {
+            return true;
+        }
+
+        // TODO(#774): This doesn't properly handle opaque instantiations where
+        // an argument is itself an instantiation because `canonical_name` does
+        // not insert the template arguments into the name, ie it for nested
+        // template arguments it creates "Foo" instead of "Foo<int>". The fully
+        // correct fix is to make `canonical_{name,path}` include template
+        // arguments properly.
+
+        let mut path = item.canonical_path(ctx);
+        let args: Vec<_> = self.template_arguments()
+            .iter()
+            .map(|arg| {
+                let arg_path = arg.canonical_path(ctx);
+                arg_path[1..].join("::")
+            }).collect();
+        {
+            let mut last = path.last_mut().unwrap();
+            last.push('<');
+            last.push_str(&args.join(", "));
+            last.push('>');
+        }
+
+        ctx.opaque_by_name(&path)
+    }
+}
+
 impl<'a> CanDeriveCopy<'a> for TemplateInstantiation {
     type Extra = ();
 
     fn can_derive_copy(&self, ctx: &BindgenContext, _: ()) -> bool {
         self.definition.can_derive_copy(ctx, ()) &&
         self.args.iter().all(|arg| arg.can_derive_copy(ctx, ()))
     }
 
     fn can_derive_copy_in_array(&self, ctx: &BindgenContext, _: ()) -> bool {
         self.definition.can_derive_copy_in_array(ctx, ()) &&
         self.args.iter().all(|arg| arg.can_derive_copy_in_array(ctx, ()))
     }
 }
 
-impl CanDeriveDebug for TemplateInstantiation {
-    type Extra = Option<Layout>;
-
-    fn can_derive_debug(&self,
-                        ctx: &BindgenContext,
-                        layout: Option<Layout>)
-                        -> bool {
-        self.args.iter().all(|arg| arg.can_derive_debug(ctx, ())) &&
-        ctx.resolve_type(self.definition)
-            .as_comp()
-            .and_then(|c| {
-                // For non-type template parameters, we generate an opaque
-                // blob, and in this case the instantiation has a better
-                // idea of the layout than the definition does.
-                if c.has_non_type_template_params() {
-                    let opaque = layout.unwrap_or(Layout::zero()).opaque();
-                    Some(opaque.can_derive_debug(ctx, ()))
-                } else {
-                    None
-                }
-            })
-            .unwrap_or_else(|| self.definition.can_derive_debug(ctx, ()))
-    }
-}
-
 impl Trace for TemplateInstantiation {
     type Extra = ();
 
     fn trace<T>(&self, _ctx: &BindgenContext, tracer: &mut T, _: &())
         where T: Tracer,
     {
         tracer.visit_kind(self.definition, EdgeKind::TemplateDeclaration);
         for &item in self.template_arguments() {
--- a/third_party/rust/bindgen/src/ir/traversal.rs
+++ b/third_party/rust/bindgen/src/ir/traversal.rs
@@ -4,17 +4,17 @@ use super::context::{BindgenContext, Ite
 use super::item::ItemSet;
 use std::collections::{BTreeMap, VecDeque};
 
 /// An outgoing edge in the IR graph is a reference from some item to another
 /// item:
 ///
 ///   from --> to
 ///
-/// The `from` is left implicit: it is the concrete `Trace` implementor which
+/// The `from` is left implicit: it is the concrete `Trace` implementer which
 /// yielded this outgoing edge.
 #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub struct Edge {
     to: ItemId,
     kind: EdgeKind,
 }
 
 impl Edge {
@@ -53,17 +53,17 @@ pub enum EdgeKind {
     /// An edge from a template instantiation to the template declaration that
     /// is being instantiated. For example, the edge from `Foo<int>` to
     /// to `Foo<T>`:
     ///
     /// ```C++
     /// template<typename T>
     /// class Foo { };
     ///
-    /// using Bar = Foo<int>;
+    /// using Bar = Foo<ant>;
     /// ```
     TemplateDeclaration,
 
     /// An edge from a template instantiation to its template argument. For
     /// example, `Foo<Bar>` to `Bar`:
     ///
     /// ```C++
     /// template<typename T>
@@ -134,16 +134,29 @@ pub enum EdgeKind {
     ///     int my_y;
     ///
     ///   public:
     ///     Foo(int x, int y);
     /// };
     /// ```
     Constructor,
 
+    /// An edge from a class or struct type to its destructor function. For
+    /// example, the edge from `Doggo` to `Doggo::~Doggo()`:
+    ///
+    /// ```C++
+    /// struct Doggo {
+    ///     char* wow;
+    ///
+    ///   public:
+    ///     ~Doggo();
+    /// };
+    /// ```
+    Destructor,
+
     /// An edge from a function declaration to its return type. For example, the
     /// edge from `foo` to `int`:
     ///
     /// ```C++
     /// int foo(char* string);
     /// ```
     FunctionReturn,
 
@@ -167,39 +180,67 @@ pub enum EdgeKind {
     TypeReference,
 }
 
 /// A predicate to allow visiting only sub-sets of the whole IR graph by
 /// excluding certain edges from being followed by the traversal.
 pub trait TraversalPredicate {
     /// Should the traversal follow this edge, and visit everything that is
     /// reachable through it?
-    fn should_follow(&self, edge: Edge) -> bool;
+    fn should_follow(&self, ctx: &BindgenContext, edge: Edge) -> bool;
 }
 
-impl TraversalPredicate for fn(Edge) -> bool {
-    fn should_follow(&self, edge: Edge) -> bool {
-        (*self)(edge)
+impl TraversalPredicate for for<'a> fn(&'a BindgenContext, Edge) -> bool {
+    fn should_follow(&self, ctx: &BindgenContext, edge: Edge) -> bool {
+        (*self)(ctx, edge)
     }
 }
 
 /// A `TraversalPredicate` implementation that follows all edges, and therefore
 /// traversals using this predicate will see the whole IR graph reachable from
 /// the traversal's roots.
-pub fn all_edges(_: Edge) -> bool {
+pub fn all_edges(_: &BindgenContext, _: Edge) -> bool {
     true
 }
 
 /// A `TraversalPredicate` implementation that never follows any edges, and
 /// therefore traversals using this predicate will only visit the traversal's
 /// roots.
-pub fn no_edges(_: Edge) -> bool {
+pub fn no_edges(_: &BindgenContext, _: Edge) -> bool {
     false
 }
 
+/// A `TraversalPredicate` implementation that only follows edges to items that
+/// are enabled for code generation. This lets us skip considering items for
+/// which are not reachable from code generation.
+pub fn codegen_edges(ctx: &BindgenContext, edge: Edge) -> bool {
+    let cc = &ctx.options().codegen_config;
+    match edge.kind {
+        EdgeKind::Generic => ctx.resolve_item(edge.to).is_enabled_for_codegen(ctx),
+
+        // We statically know the kind of item that non-generic edges can point
+        // to, so we don't need to actually resolve the item and check
+        // `Item::is_enabled_for_codegen`.
+        EdgeKind::TemplateParameterDefinition |
+        EdgeKind::TemplateArgument |
+        EdgeKind::TemplateDeclaration |
+        EdgeKind::BaseMember |
+        EdgeKind::Field |
+        EdgeKind::InnerType |
+        EdgeKind::FunctionReturn |
+        EdgeKind::FunctionParameter |
+        EdgeKind::VarType |
+        EdgeKind::TypeReference => cc.types,
+        EdgeKind::InnerVar => cc.vars,
+        EdgeKind::Method => cc.methods,
+        EdgeKind::Constructor => cc.constructors,
+        EdgeKind::Destructor => cc.destructors,
+    }
+}
+
 /// The storage for the set of items that have been seen (although their
 /// outgoing edges might not have been fully traversed yet) in an active
 /// traversal.
 pub trait TraversalStorage<'ctx, 'gen> {
     /// Construct a new instance of this TraversalStorage, for a new traversal.
     fn new(ctx: &'ctx BindgenContext<'gen>) -> Self;
 
     /// Add the given item to the storage. If the item has never been seen
@@ -345,17 +386,17 @@ pub struct ItemTraversal<'ctx, 'gen, Sto
     ctx: &'ctx BindgenContext<'gen>,
 
     /// The set of items we have seen thus far in this traversal.
     seen: Storage,
 
     /// The set of items that we have seen, but have yet to traverse.
     queue: Queue,
 
-    /// The predicate that determins which edges this traversal will follow.
+    /// The predicate that determines which edges this traversal will follow.
     predicate: Predicate,
 
     /// The item we are currently traversing.
     currently_traversing: Option<ItemId>,
 }
 
 impl<'ctx, 'gen, Storage, Queue, Predicate> ItemTraversal<'ctx,
                                                           'gen,
@@ -396,17 +437,17 @@ impl<'ctx, 'gen, Storage, Queue, Predica
     for ItemTraversal<'ctx, 'gen, Storage, Queue, Predicate>
     where 'gen: 'ctx,
           Storage: TraversalStorage<'ctx, 'gen>,
           Queue: TraversalQueue,
           Predicate: TraversalPredicate,
 {
     fn visit_kind(&mut self, item: ItemId, kind: EdgeKind) {
         let edge = Edge::new(item, kind);
-        if !self.predicate.should_follow(edge) {
+        if !self.predicate.should_follow(self.ctx, edge) {
             return;
         }
 
         let is_newly_discovered = self.seen
             .add(self.currently_traversing, item);
         if is_newly_discovered {
             self.queue.push(item)
         }
@@ -446,17 +487,17 @@ impl<'ctx, 'gen, Storage, Queue, Predica
 ///
 /// See `BindgenContext::assert_no_dangling_item_traversal` for more
 /// information.
 pub type AssertNoDanglingItemsTraversal<'ctx, 'gen> =
     ItemTraversal<'ctx,
                   'gen,
                   Paths<'ctx, 'gen>,
                   VecDeque<ItemId>,
-                  fn(Edge) -> bool>;
+                  for<'a> fn(&'a BindgenContext, Edge) -> bool>;
 
 #[cfg(test)]
 mod tests {
     use super::*;
 
     #[test]
     #[allow(dead_code)]
     fn traversal_predicate_is_object_safe() {
--- a/third_party/rust/bindgen/src/ir/ty.rs
+++ b/third_party/rust/bindgen/src/ir/ty.rs
@@ -1,25 +1,24 @@
 //! Everything related to types in our intermediate representation.
 
 use super::comp::CompInfo;
 use super::context::{BindgenContext, ItemId};
-use super::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault};
+use super::derive::{CanDeriveCopy, CanDeriveDefault};
 use super::dot::DotAttributes;
 use super::enum_ty::Enum;
 use super::function::FunctionSig;
 use super::int::IntKind;
-use super::item::Item;
+use super::item::{IsOpaque, Item};
 use super::layout::{Layout, Opaque};
 use super::objc::ObjCInterface;
 use super::template::{AsTemplateParam, TemplateInstantiation, TemplateParameters};
 use super::traversal::{EdgeKind, Trace, Tracer};
 use clang::{self, Cursor};
 use parse::{ClangItemParser, ParseError, ParseResult};
-use std::cell::Cell;
 use std::io;
 use std::mem;
 
 /// The base representation of a type in bindgen.
 ///
 /// A type has an optional name, which if present cannot be empty, a `layout`
 /// (size, alignment and packedness) if known, a `Kind`, which determines which
 /// kind of type it is, and whether the type is const.
@@ -28,19 +27,16 @@ pub struct Type {
     /// The name of the type, or None if it was an unnamed struct or union.
     name: Option<String>,
     /// The layout of the type, if known.
     layout: Option<Layout>,
     /// The inner kind of the type
     kind: TypeKind,
     /// Whether this type is const-qualified.
     is_const: bool,
-    /// Don't go into an infinite loop when detecting if we have a vtable or
-    /// not.
-    detect_has_vtable_cycle: Cell<bool>,
 }
 
 /// The maximum number of items in an array for which Rust implements common
 /// traits, and so if we have a type containing an array with more than this
 /// many items, we won't be able to derive common traits on that type.
 ///
 /// We need type-level integers yesterday :'(
 pub const RUST_DERIVE_IN_ARRAY_LIMIT: usize = 32;
@@ -70,17 +66,16 @@ impl Type {
                kind: TypeKind,
                is_const: bool)
                -> Self {
         Type {
             name: name,
             layout: layout,
             kind: kind,
             is_const: is_const,
-            detect_has_vtable_cycle: Cell::new(false),
         }
     }
 
     /// Which kind of type is this?
     pub fn kind(&self) -> &TypeKind {
         &self.kind
     }
 
@@ -97,24 +92,16 @@ impl Type {
     /// Is this a compound type?
     pub fn is_comp(&self) -> bool {
         match self.kind {
             TypeKind::Comp(..) => true,
             _ => false,
         }
     }
 
-    /// Is this type of kind `TypeKind::Opaque`?
-    pub fn is_opaque(&self) -> bool {
-        match self.kind {
-            TypeKind::Opaque => true,
-            _ => false,
-        }
-    }
-
     /// Is this type of kind `TypeKind::Named`?
     pub fn is_named(&self) -> bool {
         match self.kind {
             TypeKind::Named => true,
             _ => false,
         }
     }
 
@@ -245,39 +232,16 @@ impl Type {
                 TypeKind::ResolvedTypeRef(inner) => {
                     ctx.resolve_type(inner).layout(ctx)
                 }
                 _ => None,
             }
         })
     }
 
-    /// Whether this type has a vtable.
-    pub fn has_vtable(&self, ctx: &BindgenContext) -> bool {
-        if self.detect_has_vtable_cycle.get() {
-            return false;
-        }
-
-        self.detect_has_vtable_cycle.set(true);
-
-        // FIXME: Can we do something about template parameters? Huh...
-        let result = match self.kind {
-            TypeKind::TemplateAlias(t, _) |
-            TypeKind::Alias(t) |
-            TypeKind::ResolvedTypeRef(t) => ctx.resolve_type(t).has_vtable(ctx),
-            TypeKind::Comp(ref info) => info.has_vtable(ctx),
-            TypeKind::TemplateInstantiation(ref inst) => inst.has_vtable(ctx),
-            _ => false,
-        };
-
-        self.detect_has_vtable_cycle.set(false);
-
-        result
-    }
-
     /// Returns whether this type has a destructor.
     pub fn has_destructor(&self, ctx: &BindgenContext) -> bool {
         match self.kind {
             TypeKind::TemplateAlias(t, _) |
             TypeKind::Alias(t) |
             TypeKind::ResolvedTypeRef(t) => {
                 ctx.resolve_type(t).has_destructor(ctx)
             }
@@ -369,16 +333,30 @@ impl Type {
             TypeKind::Reference(..) |
             TypeKind::TemplateInstantiation(..) |
             TypeKind::ResolvedTypeRef(..) => true,
             _ => false,
         }
     }
 }
 
+impl IsOpaque for Type {
+    type Extra = Item;
+
+    fn is_opaque(&self, ctx: &BindgenContext, item: &Item) -> bool {
+        match self.kind {
+            TypeKind::Opaque => true,
+            TypeKind::TemplateInstantiation(ref inst) => inst.is_opaque(ctx, item),
+            TypeKind::Comp(ref comp) => comp.is_opaque(ctx, &()),
+            TypeKind::ResolvedTypeRef(to) => to.is_opaque(ctx, &()),
+            _ => false,
+        }
+    }
+}
+
 impl AsTemplateParam for Type {
     type Extra = Item;
 
     fn as_template_param(&self, ctx: &BindgenContext, item: &Item) -> Option<ItemId> {
         self.kind.as_template_param(ctx, item)
     }
 }
 
@@ -543,60 +521,30 @@ impl TemplateParameters for TypeKind {
             TypeKind::Alias(_) |
             TypeKind::ObjCId |
             TypeKind::ObjCSel |
             TypeKind::ObjCInterface(_) => None,
         }
     }
 }
 
-impl CanDeriveDebug for Type {
-    type Extra = ();
+impl<'a> CanDeriveDefault<'a> for Type {
+    type Extra = &'a Item;
 
-    fn can_derive_debug(&self, ctx: &BindgenContext, _: ()) -> bool {
-        match self.kind {
-            TypeKind::Array(t, len) => {
-                len <= RUST_DERIVE_IN_ARRAY_LIMIT && t.can_derive_debug(ctx, ())
-            }
-            TypeKind::ResolvedTypeRef(t) |
-            TypeKind::TemplateAlias(t, _) |
-            TypeKind::Alias(t) => t.can_derive_debug(ctx, ()),
-            TypeKind::Comp(ref info) => {
-                info.can_derive_debug(ctx, self.layout(ctx))
-            }
-            TypeKind::Pointer(inner) => {
-                let inner = ctx.resolve_type(inner);
-                if let TypeKind::Function(ref sig) =
-                    *inner.canonical_type(ctx).kind() {
-                    return sig.can_derive_debug(ctx, ());
-                }
-                return true;
-            }
-            TypeKind::TemplateInstantiation(ref inst) => {
-                inst.can_derive_debug(ctx, self.layout(ctx))
-            }
-            _ => true,
-        }
-    }
-}
-
-impl CanDeriveDefault for Type {
-    type Extra = ();
-
-    fn can_derive_default(&self, ctx: &BindgenContext, _: ()) -> bool {
+    fn can_derive_default(&self, ctx: &BindgenContext, item: &Item) -> bool {
         match self.kind {
             TypeKind::Array(t, len) => {
                 len <= RUST_DERIVE_IN_ARRAY_LIMIT &&
                 t.can_derive_default(ctx, ())
             }
             TypeKind::ResolvedTypeRef(t) |
             TypeKind::TemplateAlias(t, _) |
             TypeKind::Alias(t) => t.can_derive_default(ctx, ()),
             TypeKind::Comp(ref info) => {
-                info.can_derive_default(ctx, self.layout(ctx))
+                info.can_derive_default(ctx, (&item, self.layout(ctx)))
             }
             TypeKind::Opaque => {
                 self.layout
                     .map_or(true, |l| l.opaque().can_derive_default(ctx, ()))
             }
             TypeKind::Void |
             TypeKind::Named |
             TypeKind::TemplateInstantiation(..) |
@@ -771,33 +719,34 @@ pub enum TypeKind {
     ObjCSel,
 }
 
 impl Type {
     /// Whether this type is unsized, that is, has no members. This is used to
     /// derive whether we should generate a dummy `_address` field for structs,
     /// to comply to the C and C++ layouts, that specify that every type needs
     /// to be addressable.
-    pub fn is_unsized(&self, ctx: &BindgenContext) -> bool {
+    pub fn is_unsized(&self, ctx: &BindgenContext, itemid: &ItemId) -> bool {
         debug_assert!(ctx.in_codegen_phase(), "Not yet");
 
         match self.kind {
             TypeKind::Void => true,
-            TypeKind::Comp(ref ci) => ci.is_unsized(ctx),
+            TypeKind::Comp(ref ci) => ci.is_unsized(ctx, itemid),
             TypeKind::Opaque => self.layout.map_or(true, |l| l.size == 0),
             TypeKind::Array(inner, size) => {
-                size == 0 || ctx.resolve_type(inner).is_unsized(ctx)
+                size == 0 || ctx.resolve_type(inner).is_unsized(ctx, &inner)
             }
             TypeKind::ResolvedTypeRef(inner) |
             TypeKind::Alias(inner) |
             TypeKind::TemplateAlias(inner, _) => {
-                ctx.resolve_type(inner).is_unsized(ctx)
+                ctx.resolve_type(inner).is_unsized(ctx, &inner)
             }
             TypeKind::TemplateInstantiation(ref inst) => {
-                ctx.resolve_type(inst.template_definition()).is_unsized(ctx)
+                let definition = inst.template_definition();
+                ctx.resolve_type(definition).is_unsized(ctx, &definition)
             }
             TypeKind::Named |
             TypeKind::Int(..) |
             TypeKind::Float(..) |
             TypeKind::Complex(..) |
             TypeKind::Function(..) |
             TypeKind::Enum(..) |
             TypeKind::Reference(..) |
--- a/third_party/rust/bindgen/src/lib.rs
+++ b/third_party/rust/bindgen/src/lib.rs
@@ -82,19 +82,21 @@ mod codegen {
     include!(concat!(env!("OUT_DIR"), "/codegen.rs"));
 }
 
 use ir::context::{BindgenContext, ItemId};
 use ir::item::Item;
 use parse::{ClangItemParser, ParseError};
 use regex_set::RegexSet;
 
-use std::fs::OpenOptions;
+use std::fs::{File, OpenOptions};
+use std::iter;
 use std::io::{self, Write};
-use std::path::Path;
+use std::path::{Path, PathBuf};
+use std::process::{Command, Stdio};
 use std::sync::Arc;
 
 use syntax::ast;
 use syntax::codemap::{DUMMY_SP, Span};
 use syntax::print::pp::eof;
 use syntax::print::pprust;
 use syntax::ptr::P;
 
@@ -160,34 +162,37 @@ impl Default for CodegenConfig {
 /// let bindings = try!(builder().header("path/to/input/header")
 ///                              .whitelisted_type("SomeCoolClass")
 ///                              .whitelisted_function("do_some_cool_thing")
 ///                              .generate());
 ///
 /// // Write the generated bindings to an output file.
 /// try!(bindings.write_to_file("path/to/output.rs"));
 /// ```
-#[derive(Debug,Default)]
+#[derive(Debug, Default)]
 pub struct Builder {
     options: BindgenOptions,
+    input_headers: Vec<String>,
+    // Tuples of unsaved file contents of the form (name, contents).
+    input_header_contents: Vec<(String, String)>,
 }
 
 /// Construct a new [`Builder`](./struct.Builder.html).
 pub fn builder() -> Builder {
     Default::default()
 }
 
 impl Builder {
      /// Generates the command line flags use for creating `Builder`.
     pub fn command_line_flags(&self) -> Vec<String> {
         let mut output_vector: Vec<String> = Vec::new();
 
-        if let Some(ref header) = self.options.input_header {
-            //Positional argument 'header'
-            output_vector.push(header.clone().into());
+        if let Some(header) = self.input_headers.last().cloned() {
+            // Positional argument 'header'
+            output_vector.push(header);
         }
 
         self.options
             .bitfield_enums
             .get_items()
             .iter()
             .map(|item| {
                      output_vector.push("--bitfield-enum".into());
@@ -201,16 +206,26 @@ impl Builder {
             .iter()
             .map(|item| {
                      output_vector.push("--constified-enum".into());
                      output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
                  })
             .count();
 
         self.options
+            .constified_enum_modules
+            .get_items()
+            .iter()
+            .map(|item| {
+                     output_vector.push("--constified-enum-module".into());
+                     output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
+                 })
+            .count();
+
+        self.options
             .hidden_types
             .get_items()
             .iter()
             .map(|item| {
                      output_vector.push("--blacklist-type".into());
                      output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
                  })
             .count();
@@ -397,26 +412,29 @@ impl Builder {
             .get_items()
             .iter()
             .map(|item| {
                      output_vector.push("--whitelist-var".into());
                      output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
                  })
             .count();
 
+        output_vector.push("--".into());
+
         if !self.options.clang_args.is_empty() {
-            output_vector.push("--".into());
-            self.options
-                .clang_args
-                .iter()
-                .cloned()
-                .map(|item| {
-                    output_vector.push(item);
-                })
-                .count();
+            output_vector.extend(
+                self.options
+                    .clang_args
+                    .iter()
+                    .cloned()
+            );
+        }
+
+        if self.input_headers.len() > 1 {
+            output_vector.extend(self.input_headers[..self.input_headers.len() - 1].iter().cloned());
         }
 
         output_vector
     }
 
     /// Add an input C/C++ header to generate bindings for.
     ///
     /// This can be used to generate bindings to a single header:
@@ -435,31 +453,25 @@ impl Builder {
     /// let bindings = bindgen::Builder::default()
     ///     .header("first.h")
     ///     .header("second.h")
     ///     .header("third.h")
     ///     .generate()
     ///     .unwrap();
     /// ```
     pub fn header<T: Into<String>>(mut self, header: T) -> Builder {
-        if let Some(prev_header) = self.options.input_header.take() {
-            self.options.clang_args.push("-include".into());
-            self.options.clang_args.push(prev_header);
-        }
-
-        let header = header.into();
-        self.options.input_header = Some(header);
+        self.input_headers.push(header.into());
         self
     }
 
     /// Add `contents` as an input C/C++ header named `name`.
     ///
     /// The file `name` will be added to the clang arguments.
     pub fn header_contents(mut self, name: &str, contents: &str) -> Builder {
-        self.options.input_unsaved_files.push(clang::UnsavedFile::new(name, contents));
+        self.input_header_contents.push((name.into(), contents.into()));
         self
     }
 
     /// Set the output graphviz file.
     pub fn emit_ir_graphviz<T: Into<String>>(mut self, path: T) -> Builder {
         let path = path.into();
         self.options.emit_ir_graphviz = Some(path);
         self
@@ -467,17 +479,17 @@ impl Builder {
 
     /// Whether the generated bindings should contain documentation comments or
     /// not.
     ///
     /// This ideally will always be true, but it may need to be false until we
     /// implement some processing on comments to work around issues as described
     /// in:
     ///
-    /// https://github.com/servo/rust-bindgen/issues/426
+    /// https://github.com/rust-lang-nursery/rust-bindgen/issues/426
     pub fn generate_comments(mut self, doit: bool) -> Self {
         self.options.generate_comments = doit;
         self
     }
 
     /// Whether to whitelist types recursively or not. Defaults to true.
     ///
     /// This can be used to get bindgen to generate _exactly_ the types you want
@@ -496,17 +508,17 @@ impl Builder {
     }
 
     /// Whether to use the clang-provided name mangling. This is true by default
     /// and probably needed for C++ features.
     ///
     /// However, some old libclang versions seem to return incorrect results in
     /// some cases for non-mangled functions, see [1], so we allow disabling it.
     ///
-    /// [1]: https://github.com/servo/rust-bindgen/issues/528
+    /// [1]: https://github.com/rust-lang-nursery/rust-bindgen/issues/528
     pub fn trust_clang_mangling(mut self, doit: bool) -> Self {
         self.options.enable_mangling = doit;
         self
     }
 
     /// Generate a C/C++ file that includes the header and has dummy uses of
     /// every type defined in the header.
     pub fn dummy_uses<T: Into<String>>(mut self, dummy_uses: T) -> Builder {
@@ -557,26 +569,36 @@ impl Builder {
     ///
     /// This makes bindgen generate a type that isn't a rust `enum`. Regular
     /// expressions are supported.
     pub fn bitfield_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
         self.options.bitfield_enums.insert(arg);
         self
     }
 
-    /// Mark the given enum (or set of enums, if using a pattern) as being
-    /// constant.
+    /// Mark the given enum (or set of enums, if using a pattern) as a set of
+    /// constants.
     ///
     /// This makes bindgen generate constants instead of enums. Regular
     /// expressions are supported.
     pub fn constified_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
         self.options.constified_enums.insert(arg);
         self
     }
 
+    /// Mark the given enum (or set of enums, if using a pattern) as a set of
+    /// constants that should be put into a module.
+    ///
+    /// This makes bindgen generate a modules containing constants instead of
+    /// enums. Regular expressions are supported.
+    pub fn constified_enum_module<T: AsRef<str>>(mut self, arg: T) -> Builder {
+        self.options.constified_enum_modules.insert(arg);
+        self
+    }
+
     /// Add a string to prepend to the generated bindings. The string is passed
     /// through without any modification.
     pub fn raw_line<T: Into<String>>(mut self, arg: T) -> Builder {
         self.options.raw_lines.push(arg.into());
         self
     }
 
     /// Add an argument to be passed straight through to clang.
@@ -769,19 +791,117 @@ impl Builder {
 
     /// Prepend the enum name to constant or bitfield variants.
     pub fn prepend_enum_name(mut self, doit: bool) -> Self {
         self.options.prepend_enum_name = doit;
         self
     }
 
     /// Generate the Rust bindings using the options built up thus far.
-    pub fn generate<'ctx>(self) -> Result<Bindings<'ctx>, ()> {
+    pub fn generate<'ctx>(mut self) -> Result<Bindings<'ctx>, ()> {
+        self.options.input_header = self.input_headers.pop();
+        self.options.clang_args.extend(
+            self.input_headers
+                .drain(..)
+                .flat_map(|header| {
+                    iter::once("-include".into())
+                        .chain(iter::once(header))
+                })
+        );
+
+        self.options.input_unsaved_files.extend(
+            self.input_header_contents
+                .drain(..)
+                .map(|(name, contents)| clang::UnsavedFile::new(&name, &contents))
+        );
+
         Bindings::generate(self.options, None)
     }
+
+    /// Preprocess and dump the input header files to disk.
+    ///
+    /// This is useful when debugging bindgen, using C-Reduce, or when filing
+    /// issues. The resulting file will be named something like `__bindgen.i` or
+    /// `__bindgen.ii`
+    pub fn dump_preprocessed_input(&self) -> io::Result<()> {
+        let clang = clang_sys::support::Clang::find(None, &[])
+            .ok_or_else(|| io::Error::new(io::ErrorKind::Other,
+                                          "Cannot find clang executable"))?;
+
+        // The contents of a wrapper file that includes all the input header
+        // files.
+        let mut wrapper_contents = String::new();
+
+        // Whether we are working with C or C++ inputs.
+        let mut is_cpp = false;
+
+        // For each input header, add `#include "$header"`.
+        for header in &self.input_headers {
+            is_cpp |= header.ends_with(".hpp");
+
+            wrapper_contents.push_str("#include \"");
+            wrapper_contents.push_str(header);
+            wrapper_contents.push_str("\"\n");
+        }
+
+        // For each input header content, add a prefix line of `#line 0 "$name"`
+        // followed by the contents.
+        for &(ref name, ref contents) in &self.input_header_contents {
+            is_cpp |= name.ends_with(".hpp");
+
+            wrapper_contents.push_str("#line 0 \"");
+            wrapper_contents.push_str(name);
+            wrapper_contents.push_str("\"\n");
+            wrapper_contents.push_str(contents);
+        }
+
+        is_cpp |= self.options.clang_args.windows(2).any(|w| {
+            w[0] == "-x=c++" || w[1] == "-x=c++" || w == &["-x", "c++"]
+        });
+
+        let wrapper_path = PathBuf::from(if is_cpp {
+            "__bindgen.cpp"
+        } else {
+            "__bindgen.c"
+        });
+
+        {
+            let mut wrapper_file = File::create(&wrapper_path)?;
+            wrapper_file.write(wrapper_contents.as_bytes())?;
+        }
+
+        let mut cmd = Command::new(&clang.path);
+        cmd.arg("-save-temps")
+            .arg("-E")
+            .arg("-C")
+            .arg("-c")
+            .arg(&wrapper_path)
+            .stdout(Stdio::piped());
+
+        for a in &self.options.clang_args {
+            cmd.arg(a);
+        }
+
+        let mut child = cmd.spawn()?;
+
+        let mut preprocessed = child.stdout.take().unwrap();
+        let mut file = File::create(if is_cpp {
+            "__bindgen.ii"
+        } else {
+            "__bindgen.i"
+        })?;
+        io::copy(&mut preprocessed, &mut file)?;
+
+        if child.wait()?.success() {
+            Ok(())
+        } else {
+            Err(io::Error::new(io::ErrorKind::Other,
+                               "clang exited with non-zero status"))
+        }
+    }
 }
 
 /// Configuration options for generated bindings.
 ///
 /// Deprecated: use a `Builder` instead.
 #[derive(Debug)]
 #[deprecated]
 pub struct BindgenOptions {
@@ -808,16 +928,19 @@ pub struct BindgenOptions {
     pub whitelisted_vars: RegexSet,
 
     /// The enum patterns to mark an enum as bitfield.
     pub bitfield_enums: RegexSet,
 
     /// The enum patterns to mark an enum as constant.
     pub constified_enums: RegexSet,
 
+    /// The enum patterns to mark an enum as a module of constants.
+    pub constified_enum_modules: RegexSet,
+
     /// Whether we should generate builtins or not.
     pub builtins: bool,
 
     /// The set of libraries we should link in the generated Rust code.
     pub links: Vec<(String, LinkType)>,
 
     /// True if we should dump the Clang AST for debugging purposes.
     pub emit_ast: bool,
@@ -910,17 +1033,17 @@ pub struct BindgenOptions {
     pub objc_extern_crate: bool,
 
     /// Whether to use the clang-provided name mangling. This is true and
     /// probably needed for C++ features.
     ///
     /// However, some old libclang versions seem to return incorrect results in
     /// some cases for non-mangled functions, see [1], so we allow disabling it.
     ///
-    /// [1]: https://github.com/servo/rust-bindgen/issues/528
+    /// [1]: https://github.com/rust-lang-nursery/rust-bindgen/issues/528
     pub enable_mangling: bool,
 
     /// Whether to prepend the enum name to bitfield or constant variants.
     pub prepend_enum_name: bool,
 }
 
 /// TODO(emilio): This is sort of a lie (see the error message that results from
 /// removing this), but since we don't share references across panic boundaries
@@ -930,30 +1053,32 @@ impl ::std::panic::UnwindSafe for Bindge
 impl BindgenOptions {
     fn build(&mut self) {
         self.whitelisted_vars.build();
         self.whitelisted_types.build();
         self.whitelisted_functions.build();
         self.hidden_types.build();
         self.opaque_types.build();
         self.bitfield_enums.build();
+        self.constified_enum_modules.build();
         self.constified_enums.build();
     }
 }
 
 impl Default for BindgenOptions {
     fn default() -> BindgenOptions {
         BindgenOptions {
             hidden_types: Default::default(),
             opaque_types: Default::default(),
             whitelisted_types: Default::default(),
             whitelisted_functions: Default::default(),
             whitelisted_vars: Default::default(),
             bitfield_enums: Default::default(),
             constified_enums: Default::default(),
+            constified_enum_modules: Default::default(),
             builtins: false,
             links: vec![],
             emit_ast: false,
             emit_ir: false,
             emit_ir_graphviz: None,
             layout_tests: true,
             derive_debug: true,
             derive_default: false,
@@ -1032,18 +1157,45 @@ impl<'ctx> Bindings<'ctx> {
     pub fn generate(mut options: BindgenOptions,
                     span: Option<Span>)
                     -> Result<Bindings<'ctx>, ()> {
         let span = span.unwrap_or(DUMMY_SP);
         ensure_libclang_is_loaded();
 
         options.build();
 
+        // Filter out include paths and similar stuff, so we don't incorrectly
+        // promote them to `-isystem`.
+        let clang_args_for_clang_sys = {
+            let mut last_was_include_prefix = false;
+            options.clang_args.iter().filter(|arg| {
+                if last_was_include_prefix {
+                    last_was_include_prefix = false;
+                    return false;
+                }
+
+                let arg = &**arg;
+
+                // https://clang.llvm.org/docs/ClangCommandLineReference.html
+                // -isystem and -isystem-after are harmless.
+                if arg == "-I" || arg == "--include-directory" {
+                    last_was_include_prefix = true;
+                    return false;
+                }
+
+                if arg.starts_with("-I") || arg.starts_with("--include-directory=") {
+                    return false;
+                }
+
+                true
+            }).cloned().collect::<Vec<_>>()
+        };
+
         // TODO: Make this path fixup configurable?
-        if let Some(clang) = clang_sys::support::Clang::find(None) {
+        if let Some(clang) = clang_sys::support::Clang::find(None, &clang_args_for_clang_sys) {
             // If --target is specified, assume caller knows what they're doing
             // and don't mess with include paths for them
             let has_target_arg = options.clang_args
                 .iter()
                 .rposition(|arg| arg.starts_with("--target"))
                 .is_some();
             if !has_target_arg {
                 // TODO: distinguish C and C++ paths? C++'s should be enough, I
--- a/third_party/rust/bindgen/src/main.rs
+++ b/third_party/rust/bindgen/src/main.rs
@@ -75,14 +75,14 @@ pub fn main() {
             std::process::exit(1);
         }
     };
 }
 
 fn print_verbose_err() {
     println!("Bindgen unexpectedly panicked");
     println!("This may be caused by one of the known-unsupported \
-              things (https://github.com/servo/rust-bindgen#c), \
+              things (https://github.com/rust-lang-nursery/rust-bindgen#c), \
               please modify the bindgen flags to work around it as \
-              described in https://github.com/servo/rust-bindgen#c");
+              described in https://github.com/rust-lang-nursery/rust-bindgen#c");
     println!("Otherwise, please file an issue at \
-              https://github.com/servo/rust-bindgen/issues/new");
+              https://github.com/rust-lang-nursery/rust-bindgen/issues/new");
 }
--- a/third_party/rust/bindgen/src/options.rs
+++ b/third_party/rust/bindgen/src/options.rs
@@ -28,16 +28,25 @@ pub fn builder_from_flags<I>
             Arg::with_name("constified-enum")
                 .long("constified-enum")
                 .help("Mark any enum whose name matches <regex> as a set of \
                        constants instead of an enumeration.")
                 .value_name("regex")
                 .takes_value(true)
                 .multiple(true)
                 .number_of_values(1),
+            Arg::with_name("constified-enum-module")
+                .long("constified-enum-module")
+                .help("Mark any enum whose name matches <regex> as a module of \
+                       constants instead of an enumeration. This option \
+                       implies \"--constified-enum.\"")
+                .value_name("regex")
+                .takes_value(true)
+                .multiple(true)
+                .number_of_values(1),
             Arg::with_name("blacklist-type")
                 .long("blacklist-type")
                 .help("Mark <type> as hidden.")
                 .value_name("type")
                 .takes_value(true)
                 .multiple(true)
                 .number_of_values(1),
             Arg::with_name("no-layout-tests")
@@ -51,17 +60,17 @@ pub fn builder_from_flags<I>
                 .hidden(true)
                 .help("Avoid deriving Default on any type."),
             Arg::with_name("with-derive-default")
                 .long("with-derive-default")
                 .help("Derive Default on any type."),
             Arg::with_name("no-doc-comments")
                 .long("no-doc-comments")
                 .help("Avoid including doc comments in the output, see: \
-                      https://github.com/servo/rust-bindgen/issues/426"),
+                      https://github.com/rust-lang-nursery/rust-bindgen/issues/426"),
             Arg::with_name("no-recursive-whitelist")
                 .long("no-recursive-whitelist")
                 .help("Avoid whitelisting types recursively."),
             Arg::with_name("objc-extern-crate")
                 .long("objc-extern-crate")
                 .help("Use extern crate instead of use for objc."),
             Arg::with_name("distrust-clang-mangling")
                 .long("distrust-clang-mangling")
@@ -200,16 +209,22 @@ pub fn builder_from_flags<I>
                        generated.")
                 .value_name("regex")
                 .takes_value(true)
                 .multiple(true)
                 .number_of_values(1),
             Arg::with_name("verbose")
                 .long("verbose")
                 .help("Print verbose error messages."),
+            Arg::with_name("dump-preprocessed-input")
+                .long("dump-preprocessed-input")
+                .help("Preprocess and dump the input header files to disk. \
+                       Useful when debugging bindgen, using C-Reduce, or when \
+                       filing issues. The resulting file will be named \
+                       something like `__bindgen.i` or `__bindgen.ii`.")
         ]) // .args()
         .get_matches_from(args);
 
     let mut builder = builder();
 
     if let Some(header) = matches.value_of("header") {
         builder = builder.header(header);
     } else {
@@ -217,22 +232,27 @@ pub fn builder_from_flags<I>
     }
 
     if let Some(bitfields) = matches.values_of("bitfield-enum") {
         for regex in bitfields {
             builder = builder.bitfield_enum(regex);
         }
     }
 
-    if let Some(bitfields) = matches.values_of("constified-enum") {
-        for regex in bitfields {
+    if let Some(constifieds) = matches.values_of("constified-enum") {
+        for regex in constifieds {
             builder = builder.constified_enum(regex);
         }
     }
 
+    if let Some(constified_mods) = matches.values_of("constified-enum-module") {
+        for regex in constified_mods {
+            builder = builder.constified_enum_module(regex);
+        }
+    }
     if let Some(hidden_types) = matches.values_of("blacklist-type") {
         for ty in hidden_types {
             builder = builder.hide_type(ty);
         }
     }
 
     if matches.is_present("builtins") {
         builder = builder.emit_builtins();
@@ -277,19 +297,20 @@ pub fn builder_from_flags<I>
         for what in what_to_generate.split(",") {
             match what {
                 "functions" => config.functions = true,
                 "types" => config.types = true,
                 "vars" => config.vars = true,
                 "methods" => config.methods = true,
                 "constructors" => config.constructors = true,
                 "destructors" => config.destructors = true,
-                _ => {
+                otherwise => {
                     return Err(Error::new(ErrorKind::Other,
-                                          "Unknown generate item"));
+                                          format!("Unknown generate item: {}",
+                                                  otherwise)));
                 }
             }
         }
         builder = builder.with_codegen_config(config);
     }
 
     if matches.is_present("emit-clang-ast") {
         builder = builder.emit_clang_ast();
@@ -405,12 +426,16 @@ pub fn builder_from_flags<I>
 
     let output = if let Some(path) = matches.value_of("output") {
         let file = try!(File::create(path));
         Box::new(io::BufWriter::new(file)) as Box<io::Write>
     } else {
         Box::new(io::BufWriter::new(io::stdout())) as Box<io::Write>
     };
 
+    if matches.is_present("dump-preprocessed-input") {
+        builder.dump_preprocessed_input()?;
+    }
+
     let verbose = matches.is_present("verbose");
 
     Ok((builder, output, verbose))
 }
--- a/third_party/rust/bindgen/src/uses.rs
+++ b/third_party/rust/bindgen/src/uses.rs
@@ -67,16 +67,18 @@ pub fn generate_dummy_uses<W>(ctx: &mut 
             .expect("Should not generate dummy uses without an input header");
 
         try!(writeln!(dest, "/* automatically generated by rust-bindgen */"));
         try!(writeln!(dest, ""));
         try!(writeln!(dest, "#include \"{}\"", input_header));
         try!(writeln!(dest, ""));
 
         let type_items = ctx.whitelisted_items()
+            .iter()
+            .cloned()
             .map(|id| ctx.resolve_item(id))
             .filter(|item| {
                 // We only want type items.
                 if let Some(ty) = item.kind().as_type() {
                     // However, we don't want anonymous types, as we can't
                     // generate dummy uses for them.
                     ty.name().is_some() &&
                         // Nor do we want builtin types or named template type
--- 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",".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
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".travis.yml":"79d6a139814ae0f06ce0ca85fe22a27316a27d444320b904c471c7f612129889","CHANGELOG.md":"bd7194bb4c1572c3c34764853a871649bb4f8a20bd7fe6ef96aa8c49d3eb79a9","CONTRIBUTING.md":"4e2a45992604f07a37030bb1fc598c6f54a1785747c4f37a15a37481bbdecce8","Cargo.toml":"5f1795410761466bc3fbcec96a4f5d560b6ccf681bfa86b337fcf3b83ee074cb","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":"7576ac0decd8827f2454af80631f8c7a852c0b56c28c0b08e03274a7c6e26ab0","src/link.rs":"b9f76e26fa9b1d690f6abf17e9f898d6545be149e2afe64c7411cd53e3168fcf","src/support.rs":"174534f4963a841de7c4fe14d9db6930355d99e5497ac38f42c9006440be02ef","tests/header.h":"b1cf564b21d76db78529d1934e1481a5f0452fdedc6e32954608293c310498b6","tests/lib.rs":"cc0544b0e580d79ae7a7ce0f390f979b3fabe85370b29318d5fc51c9de92599d"},"package":"611ec2e3a7623afd8a8c0d027887b6b55759d894abbf5fe11b9dc11b50d5b49a"}
\ No newline at end of file
--- 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.18.0"
+version = "0.19.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"
@@ -30,17 +30,17 @@ gte_clang_3_8 = []
 gte_clang_3_9 = []
 gte_clang_4_0 = []
 
 runtime = ["libloading"]
 static = []
 
 [dependencies]
 
-bitflags = "0.8.0"
+bitflags = "0.9.1"
 glob = "0.2.11"
 libc = "0.2.14"
 libloading = { version = "0.4.0", optional = true }
 
 clippy = { version = "0.0.*", optional = true }
 
 [build-dependencies]
 
--- a/third_party/rust/clang-sys/src/lib.rs
+++ b/third_party/rust/clang-sys/src/lib.rs
@@ -784,167 +784,167 @@ cenum! {
 }
 
 //================================================
 // Flags
 //================================================
 
 bitflags! {
     #[repr(C)]
-    pub flags CXCodeComplete_Flags: c_uint {
-        const CXCodeComplete_IncludeMacros = 1,
-        const CXCodeComplete_IncludeCodePatterns = 2,
-        const CXCodeComplete_IncludeBriefComments = 4,
+    pub struct CXCodeComplete_Flags: c_uint {
+        const CXCodeComplete_IncludeMacros = 1;
+        const CXCodeComplete_IncludeCodePatterns = 2;
+        const CXCodeComplete_IncludeBriefComments = 4;
     }
 }
 
 bitflags! {
     #[repr(C)]
-    pub flags CXCompletionContext: c_uint {
-        const CXCompletionContext_Unexposed = 0,
-        const CXCompletionContext_AnyType = 1,
-        const CXCompletionContext_AnyValue = 2,
-        const CXCompletionContext_ObjCObjectValue = 4,
-        const CXCompletionContext_ObjCSelectorValue = 8,
-        const CXCompletionContext_CXXClassTypeValue = 16,
-        const CXCompletionContext_DotMemberAccess = 32,
-        const CXCompletionContext_ArrowMemberAccess = 64,
-        const CXCompletionContext_ObjCPropertyAccess = 128,
-        const CXCompletionContext_EnumTag = 256,
-        const CXCompletionContext_UnionTag = 512,
-        const CXCompletionContext_StructTag = 1024,
-        const CXCompletionContext_ClassTag = 2048,
-        const CXCompletionContext_Namespace = 4096,
-        const CXCompletionContext_NestedNameSpecifier = 8192,
-        const CXCompletionContext_ObjCInterface = 16384,
-        const CXCompletionContext_ObjCProtocol = 32768,
-        const CXCompletionContext_ObjCCategory = 65536,
-        const CXCompletionContext_ObjCInstanceMessage = 131072,
-        const CXCompletionContext_ObjCClassMessage = 262144,
-        const CXCompletionContext_ObjCSelectorName = 524288,
-        const CXCompletionContext_MacroName = 1048576,
-        const CXCompletionContext_NaturalLanguage = 2097152,
-        const CXCompletionContext_Unknown = 4194303,
+    pub struct CXCompletionContext: c_uint {
+        const CXCompletionContext_Unexposed = 0;
+        const CXCompletionContext_AnyType = 1;
+        const CXCompletionContext_AnyValue = 2;
+        const CXCompletionContext_ObjCObjectValue = 4;
+        const CXCompletionContext_ObjCSelectorValue = 8;
+        const CXCompletionContext_CXXClassTypeValue = 16;
+        const CXCompletionContext_DotMemberAccess = 32;
+        const CXCompletionContext_ArrowMemberAccess = 64;
+        const CXCompletionContext_ObjCPropertyAccess = 128;
+        const CXCompletionContext_EnumTag = 256;
+        const CXCompletionContext_UnionTag = 512;
+        const CXCompletionContext_StructTag = 1024;
+        const CXCompletionContext_ClassTag = 2048;
+        const CXCompletionContext_Namespace = 4096;
+        const CXCompletionContext_NestedNameSpecifier = 8192;
+        const CXCompletionContext_ObjCInterface = 16384;
+        const CXCompletionContext_ObjCProtocol = 32768;
+        const CXCompletionContext_ObjCCategory = 65536;
+        const CXCompletionContext_ObjCInstanceMessage = 131072;
+        const CXCompletionContext_ObjCClassMessage = 262144;
+        const CXCompletionContext_ObjCSelectorName = 524288;
+        const CXCompletionContext_MacroName = 1048576;
+        const CXCompletionContext_NaturalLanguage = 2097152;
+        const CXCompletionContext_Unknown = 4194303;
     }
 }
 
 bitflags! {
     #[repr(C)]
-    pub flags CXDiagnosticDisplayOptions: c_uint {
-        const CXDiagnostic_DisplaySourceLocation = 1,
-        const CXDiagnostic_DisplayColumn = 2,
-        const CXDiagnostic_DisplaySourceRanges = 4,
-        const CXDiagnostic_DisplayOption = 8,
-        const CXDiagnostic_DisplayCategoryId = 16,
-        const CXDiagnostic_DisplayCategoryName = 32,
+    pub struct CXDiagnosticDisplayOptions: c_uint {
+        const CXDiagnostic_DisplaySourceLocation = 1;
+        const CXDiagnostic_DisplayColumn = 2;
+        const CXDiagnostic_DisplaySourceRanges = 4;
+        const CXDiagnostic_DisplayOption = 8;
+        const CXDiagnostic_DisplayCategoryId = 16;
+        const CXDiagnostic_DisplayCategoryName = 32;
     }
 }
 
 bitflags! {
     #[repr(C)]
-    pub flags CXGlobalOptFlags: c_uint {
-        const CXGlobalOpt_None = 0,
-        const CXGlobalOpt_ThreadBackgroundPriorityForIndexing = 1,
-        const CXGlobalOpt_ThreadBackgroundPriorityForEditing = 2,
-        const CXGlobalOpt_ThreadBackgroundPriorityForAll = 3,
+    pub struct CXGlobalOptFlags: c_uint {
+        const CXGlobalOpt_None = 0;
+        const CXGlobalOpt_ThreadBackgroundPriorityForIndexing = 1;
+        const CXGlobalOpt_ThreadBackgroundPriorityForEditing = 2;
+        const CXGlobalOpt_ThreadBackgroundPriorityForAll = 3;
     }
 }
 
 bitflags! {
     #[repr(C)]
-    pub flags CXIdxDeclInfoFlags: c_uint {
-        const CXIdxDeclFlag_Skipped = 1,
+    pub struct CXIdxDeclInfoFlags: c_uint {
+        const CXIdxDeclFlag_Skipped = 1;
     }
 }
 
 bitflags! {
     #[repr(C)]
-    pub flags CXIndexOptFlags: c_uint {
-        const CXIndexOptNone = 0,
-        const CXIndexOptSuppressRedundantRefs = 1,
-        const CXIndexOptIndexFunctionLocalSymbols = 2,
-        const CXIndexOptIndexImplicitTemplateInstantiations = 4,
-        const CXIndexOptSuppressWarnings = 8,
-        const CXIndexOptSkipParsedBodiesInSession = 16,
+    pub struct CXIndexOptFlags: c_uint {
+        const CXIndexOptNone = 0;
+        const CXIndexOptSuppressRedundantRefs = 1;
+        const CXIndexOptIndexFunctionLocalSymbols = 2;
+        const CXIndexOptIndexImplicitTemplateInstantiations = 4;
+        const CXIndexOptSuppressWarnings = 8;
+        const CXIndexOptSkipParsedBodiesInSession = 16;
     }
 }
 
 bitflags! {
     #[repr(C)]
-    pub flags CXNameRefFlags: c_uint {
-        const CXNameRange_WantQualifier = 1,
-        const CXNameRange_WantTemplateArgs = 2,
-        const CXNameRange_WantSinglePiece = 4
+    pub struct CXNameRefFlags: c_uint {
+        const CXNameRange_WantQualifier = 1;
+        const CXNameRange_WantTemplateArgs = 2;
+        const CXNameRange_WantSinglePiece = 4;
     }
 }
 
 bitflags! {
     #[repr(C)]
-    pub flags CXObjCDeclQualifierKind: c_uint {
-        const CXObjCDeclQualifier_None = 0,
-        const CXObjCDeclQualifier_In = 1,
-        const CXObjCDeclQualifier_Inout = 2,
-        const CXObjCDeclQualifier_Out = 4,
-        const CXObjCDeclQualifier_Bycopy = 8,
-        const CXObjCDeclQualifier_Byref = 16,
-        const CXObjCDeclQualifier_Oneway = 32,
+    pub struct CXObjCDeclQualifierKind: c_uint {
+        const CXObjCDeclQualifier_None = 0;
+        const CXObjCDeclQualifier_In = 1;
+        const CXObjCDeclQualifier_Inout = 2;
+        const CXObjCDeclQualifier_Out = 4;
+        const CXObjCDeclQualifier_Bycopy = 8;
+        const CXObjCDeclQualifier_Byref = 16;
+        const CXObjCDeclQualifier_Oneway = 32;
     }
 }
 
 bitflags! {
     #[repr(C)]
-    pub flags CXObjCPropertyAttrKind: c_uint {
-        const CXObjCPropertyAttr_noattr = 0,
-        const CXObjCPropertyAttr_readonly = 1,
-        const CXObjCPropertyAttr_getter = 2,
-        const CXObjCPropertyAttr_assign = 4,
-        const CXObjCPropertyAttr_readwrite = 8,
-        const CXObjCPropertyAttr_retain = 16,
-        const CXObjCPropertyAttr_copy = 32,
-        const CXObjCPropertyAttr_nonatomic = 64,
-        const CXObjCPropertyAttr_setter = 128,
-        const CXObjCPropertyAttr_atomic = 256,
-        const CXObjCPropertyAttr_weak = 512,
-        const CXObjCPropertyAttr_strong = 1024,
-        const CXObjCPropertyAttr_unsafe_unretained = 2048,
+    pub struct CXObjCPropertyAttrKind: c_uint {
+        const CXObjCPropertyAttr_noattr = 0;
+        const CXObjCPropertyAttr_readonly = 1;
+        const CXObjCPropertyAttr_getter = 2;
+        const CXObjCPropertyAttr_assign = 4;
+        const CXObjCPropertyAttr_readwrite = 8;
+        const CXObjCPropertyAttr_retain = 16;
+        const CXObjCPropertyAttr_copy = 32;
+        const CXObjCPropertyAttr_nonatomic = 64;
+        const CXObjCPropertyAttr_setter = 128;
+        const CXObjCPropertyAttr_atomic = 256;
+        const CXObjCPropertyAttr_weak = 512;
+        const CXObjCPropertyAttr_strong = 1024;
+        const CXObjCPropertyAttr_unsafe_unretained = 2048;
         #[cfg(feature="gte_clang_3_9")]
-        const CXObjCPropertyAttr_class = 4096,
+        const CXObjCPropertyAttr_class = 4096;
     }
 }
 
 bitflags! {
     #[repr(C)]
-    pub flags CXReparse_Flags: c_uint {
-        const CXReparse_None = 0,
+    pub struct CXReparse_Flags: c_uint {
+        const CXReparse_None = 0;
     }
 }
 
 bitflags! {
     #[repr(C)]
-    pub flags CXSaveTranslationUnit_Flags: c_uint {
-        const CXSaveTranslationUnit_None = 0,
+    pub struct CXSaveTranslationUnit_Flags: c_uint {
+        const CXSaveTranslationUnit_None = 0;
     }
 }
 
 bitflags! {
     #[repr(C)]
-    pub flags CXTranslationUnit_Flags: c_uint {
-        const CXTranslationUnit_None = 0,
-        const CXTranslationUnit_DetailedPreprocessingRecord = 1,
-        const CXTranslationUnit_Incomplete = 2,
-        const CXTranslationUnit_PrecompiledPreamble = 4,
-        const CXTranslationUnit_CacheCompletionResults = 8,
-        const CXTranslationUnit_ForSerialization = 16,
-        const CXTranslationUnit_CXXChainedPCH = 32,
-        const CXTranslationUnit_SkipFunctionBodies = 64,
-        const CXTranslationUnit_IncludeBriefCommentsInCodeCompletion = 128,
+    pub struct CXTranslationUnit_Flags: c_uint {
+        const CXTranslationUnit_None = 0;
+        const CXTranslationUnit_DetailedPreprocessingRecord = 1;
+        const CXTranslationUnit_Incomplete = 2;
+        const CXTranslationUnit_PrecompiledPreamble = 4;
+        const CXTranslationUnit_CacheCompletionResults = 8;
+        const CXTranslationUnit_ForSerialization = 16;
+        const CXTranslationUnit_CXXChainedPCH = 32;
+        const CXTranslationUnit_SkipFunctionBodies = 64;
+        const CXTranslationUnit_IncludeBriefCommentsInCodeCompletion = 128;
         #[cfg(feature="gte_clang_3_8")]
-        const CXTranslationUnit_CreatePreambleOnFirstParse = 256,
+        const CXTranslationUnit_CreatePreambleOnFirstParse = 256;
         #[cfg(feature="gte_clang_3_9")]
-        const CXTranslationUnit_KeepGoing = 512,
+        const CXTranslationUnit_KeepGoing = 512;
     }
 }
 
 //================================================
 // Structs
 //================================================
 
 // Opaque ________________________________________
--- a/third_party/rust/clang-sys/src/support.rs
+++ b/third_party/rust/clang-sys/src/support.rs
@@ -54,38 +54,38 @@ pub struct Clang {
     pub c_search_paths: Option<Vec<PathBuf>>,
     /// The directories searched by this `clang` executable for C++ headers if they could be parsed.
     pub cpp_search_paths: Option<Vec<PathBuf>>,
 }
 
 impl Clang {
     //- Constructors -----------------------------
 
-    fn new(path: PathBuf) -> Clang {
+    fn new(path: PathBuf, args: &[String]) -> Clang {
         let version = parse_version(&path);
-        let c_search_paths = parse_search_paths(&path, "c");
-        let cpp_search_paths = parse_search_paths(&path, "c++");
+        let c_search_paths = parse_search_paths(&path, "c", args);
+        let cpp_search_paths = parse_search_paths(&path, "c++", args);
         Clang {
             path: path,
             version: version,
             c_search_paths: c_search_paths,
             cpp_search_paths: cpp_search_paths,
         }
     }
 
     /// Returns a `clang` executable if one can be found.
     ///
     /// If the `CLANG_PATH` environment variable is set, that is the instance of `clang` used.
     /// Otherwise, a series of directories are searched. First, If a path is supplied, that is the
     /// first directory searched. Then, the directory returned by `llvm-config --bindir` is
     /// searched. On OS X systems, `xcodebuild -find clang` will next be queried. Last, the
     /// directories in the system's `PATH` are searched.
-    pub fn find(path: Option<&Path>) -> Option<Clang> {
+    pub fn find(path: Option<&Path>, args: &[String]) -> Option<Clang> {
         if let Ok(path) = env::var("CLANG_PATH") {
-            return Some(Clang::new(path.into()));
+            return Some(Clang::new(path.into(), args));
         }
 
         let mut paths = vec![];
         if let Some(path) = path {
             paths.push(path.into());
         }
         if let Ok(path) = run_llvm_config(&["--bindir"]) {
             paths.push(path.into());
@@ -97,17 +97,17 @@ impl Clang {
         }
         paths.extend(env::split_paths(&env::var("PATH").unwrap()));
 
         let default = format!("clang{}", env::consts::EXE_SUFFIX);
         let versioned = format!("clang-[0-9]*{}", env::consts::EXE_SUFFIX);
         let patterns = &[&default[..], &versioned[..]];
         for path in paths {
             if let Some(path) = find(&path, patterns) {
-                return Some(Clang::new(path));
+                return Some(Clang::new(path, args));
             }
         }
         None
     }
 }
 
 //================================================
 // Functions
@@ -174,15 +174,17 @@ fn parse_version(path: &Path) -> Option<
     let mut numbers = try_opt!(output[start..].split_whitespace().nth(0)).split('.');
     let major = try_opt!(numbers.next().and_then(parse_version_number));
     let minor = try_opt!(numbers.next().and_then(parse_version_number));
     let subminor = numbers.next().and_then(parse_version_number).unwrap_or(0);
     Some(CXVersion { Major: major, Minor: minor, Subminor: subminor })
 }
 
 /// Parses the search paths from the output of a `clang` executable if possible.
-fn parse_search_paths(path: &Path, language: &str) -> Option<Vec<PathBuf>> {
-    let output = run_clang(path, &["-E", "-x", language, "-", "-v"]).1;
+fn parse_search_paths(path: &Path, language: &str, args: &[String]) -> Option<Vec<PathBuf>> {
+    let mut clang_args = vec!["-E", "-x", language, "-", "-v"];
+    clang_args.extend(args.iter().map(|s| &**s));
+    let output = run_clang(path, &clang_args).1;
     let start = try_opt!(output.find("#include <...> search starts here:")) + 34;
     let end = try_opt!(output.find("End of search list."));
     let paths = output[start..end].replace("(framework directory)", "");
     Some(paths.lines().filter(|l| !l.is_empty()).map(|l| Path::new(l.trim()).into()).collect())
 }
--- a/third_party/rust/clang-sys/tests/lib.rs
+++ b/third_party/rust/clang-sys/tests/lib.rs
@@ -36,11 +36,11 @@ fn test() {
 #[cfg(not(feature="runtime"))]
 #[test]
 fn test() {
     parse();
 }
 
 #[test]
 fn test_support() {
-    let clang = support::Clang::find(None).unwrap();
+    let clang = support::Clang::find(None, &[]).unwrap();
     println!("{:?}", clang);
 }
--- a/toolkit/library/gtest/rust/Cargo.lock
+++ b/toolkit/library/gtest/rust/Cargo.lock
@@ -84,23 +84,23 @@ 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 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "bindgen"
-version = "0.26.1"
+version = "0.29.0"
 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.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clang-sys 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "clap 2.24.2 (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)",
@@ -155,20 +155,20 @@ 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.18.0"
+version = "0.19.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)",
+ "bitflags 0.9.1 (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.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "libloading 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "clap"
 version = "2.24.2"
@@ -922,17 +922,17 @@ source = "registry+https://github.com/ru
 [[package]]
 name = "style"
 version = "0.0.1"
 dependencies = [
  "app_units 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "arraydeque 0.2.3 (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.26.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bindgen 0.29.0 (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.18.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.15.1 (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)",
@@ -1261,27 +1261,27 @@ dependencies = [
 "checksum app_units 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b502f30531df49d388ac6efbc8fb25652d54df5cc2bca653361f683c6dd2f075"
 "checksum arraydeque 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "96e774cadb24c2245225280c6799793f9802b918a58a79615e9490607489a717"
 "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 atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159"
 "checksum binary-space-partition 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88ceb0d16c4fd0e42876e298d7d3ce3780dd9ebdcbe4199816a32c77e08597ff"
 "checksum bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e103c8b299b28a9c6990458b7013dc4a8356a9b854c51b9883241f5866fac36e"
-"checksum bindgen 0.26.1 (registry+https://github.com/rust-lang/crates.io-index)" = "04488a91af8f15eec4d88eb59e2c4e982c03ff31582acf2f5623e2e6d8ae9e0b"
+"checksum bindgen 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0c338079dafc81bef7d581f494b906603d12359c4306979eae6ca081925a4984"
 "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 bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
 "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.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff7c2d1502c65748c7221f43ce670b3ba5c697acebfeb85a580827daca6975fc"
+"checksum clang-sys 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "611ec2e3a7623afd8a8c0d027887b6b55759d894abbf5fe11b9dc11b50d5b49a"
 "checksum clap 2.24.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b8f69e518f967224e628896b54e41ff6acfb4dcfefc5076325c36525dac900f"
 "checksum coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c06169f5beb7e31c7c67ebf5540b8b472d23e3eade3b2ec7d1f5b504a85f91bd"
 "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.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a9f841e9637adec70838c537cae52cb4c751cc6514ad05669b51d107c2021c79"
 "checksum core-text 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16ce16d9ed00181016c11ff48e561314bec92bfbce9fe48f319366618d4e5de6"
 "checksum cssparser 0.18.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c89e2d77451da8a55f1f2fcaf7eb86c32da9296890c6a474c7e4047f2429b2f4"
 "checksum cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "079adec4af52bb5275eadd004292028c79eb3c5f5b4ee8086a36d4197032f6df"
--- a/toolkit/library/rust/Cargo.lock
+++ b/toolkit/library/rust/Cargo.lock
@@ -82,23 +82,23 @@ 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 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "bindgen"
-version = "0.26.1"
+version = "0.29.0"
 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.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clang-sys 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "clap 2.24.2 (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)",
@@ -153,20 +153,20 @@ 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.18.0"
+version = "0.19.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)",
+ "bitflags 0.9.1 (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.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "libloading 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "clap"
 version = "2.24.2"
@@ -909,17 +909,17 @@ source = "registry+https://github.com/ru
 [[package]]
 name = "style"
 version = "0.0.1"
 dependencies = [
  "app_units 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "arraydeque 0.2.3 (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.26.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bindgen 0.29.0 (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.18.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.15.1 (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)",
@@ -1248,27 +1248,27 @@ dependencies = [
 "checksum app_units 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b502f30531df49d388ac6efbc8fb25652d54df5cc2bca653361f683c6dd2f075"
 "checksum arraydeque 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "96e774cadb24c2245225280c6799793f9802b918a58a79615e9490607489a717"
 "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 atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159"
 "checksum binary-space-partition 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88ceb0d16c4fd0e42876e298d7d3ce3780dd9ebdcbe4199816a32c77e08597ff"
 "checksum bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e103c8b299b28a9c6990458b7013dc4a8356a9b854c51b9883241f5866fac36e"
-"checksum bindgen 0.26.1 (registry+https://github.com/rust-lang/crates.io-index)" = "04488a91af8f15eec4d88eb59e2c4e982c03ff31582acf2f5623e2e6d8ae9e0b"
+"checksum bindgen 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0c338079dafc81bef7d581f494b906603d12359c4306979eae6ca081925a4984"
 "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 bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
 "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.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff7c2d1502c65748c7221f43ce670b3ba5c697acebfeb85a580827daca6975fc"
+"checksum clang-sys 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "611ec2e3a7623afd8a8c0d027887b6b55759d894abbf5fe11b9dc11b50d5b49a"
 "checksum clap 2.24.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b8f69e518f967224e628896b54e41ff6acfb4dcfefc5076325c36525dac900f"
 "checksum coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c06169f5beb7e31c7c67ebf5540b8b472d23e3eade3b2ec7d1f5b504a85f91bd"
 "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.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a9f841e9637adec70838c537cae52cb4c751cc6514ad05669b51d107c2021c79"
 "checksum core-text 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16ce16d9ed00181016c11ff48e561314bec92bfbce9fe48f319366618d4e5de6"
 "checksum cssparser 0.18.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c89e2d77451da8a55f1f2fcaf7eb86c32da9296890c6a474c7e4047f2429b2f4"
 "checksum cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "079adec4af52bb5275eadd004292028c79eb3c5f5b4ee8086a36d4197032f6df"