Bug 1340407 - revendor rust dependencies after 2017-02-16 servo commits
authorCameron McCormack <cam@mcc.id.au>
Fri, 17 Feb 2017 12:20:24 +0800
changeset 372406 b1fe40830bdbb5001698a5a7d3a68959852d37ac
parent 372405 bc92ac281e5e560853dd6e7939a37e7d401608dd
child 372407 754d988fc8702e445ebe597448f645b7bd252922
push id10863
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 23:02:23 +0000
treeherdermozilla-aurora@0931190cd725 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1340407
milestone54.0a1
Bug 1340407 - revendor rust dependencies after 2017-02-16 servo commits CLOSED TREE
third_party/rust/bindgen/.cargo-checksum.json
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/build.rs
third_party/rust/bindgen/src/chooser.rs
third_party/rust/bindgen/src/clang.rs
third_party/rust/bindgen/src/codegen/mod.rs
third_party/rust/bindgen/src/codegen/struct_layout.rs
third_party/rust/bindgen/src/ir/comp.rs
third_party/rust/bindgen/src/ir/context.rs
third_party/rust/bindgen/src/ir/derive.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/item_kind.rs
third_party/rust/bindgen/src/ir/layout.rs
third_party/rust/bindgen/src/ir/mod.rs
third_party/rust/bindgen/src/ir/named.rs
third_party/rust/bindgen/src/ir/objc.rs
third_party/rust/bindgen/src/ir/traversal.rs
third_party/rust/bindgen/src/ir/ty.rs
third_party/rust/bindgen/src/ir/type_collector.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/tests/headers/bitfield_align.h
third_party/rust/bindgen/tests/headers/class_nested.hpp
third_party/rust/bindgen/tests/headers/const_array_fn_arg.h
third_party/rust/bindgen/tests/headers/issue-446.hpp
third_party/rust/bindgen/tests/headers/issue-493.hpp
third_party/rust/bindgen/tests/headers/layout.h
third_party/rust/bindgen/tests/headers/layout_align.h
third_party/rust/bindgen/tests/headers/layout_arp.h
third_party/rust/bindgen/tests/headers/layout_array.h
third_party/rust/bindgen/tests/headers/layout_cmdline_token.h
third_party/rust/bindgen/tests/headers/layout_eth_conf.h
third_party/rust/bindgen/tests/headers/layout_kni_mbuf.h
third_party/rust/bindgen/tests/headers/layout_mbuf.h
third_party/rust/bindgen/tests/headers/no-derive-debug.h
third_party/rust/bindgen/tests/headers/no-derive-default.h
third_party/rust/bindgen/tests/headers/objc_method.h
third_party/rust/bindgen/tests/headers/struct_typedef.h
third_party/rust/bindgen/tests/headers/struct_typedef_ns.hpp
third_party/rust/bindgen/tests/headers/template_partial_specification.hpp
third_party/rust/bindgen/tests/headers/unknown_attr.h
third_party/rust/bindgen/tests/headers/use-core.h
third_party/rust/bindgen/tests/tests.rs
third_party/rust/clang-sys/.cargo-checksum.json
third_party/rust/clang-sys/CHANGELOG.md
third_party/rust/clang-sys/Cargo.toml
third_party/rust/clang-sys/src/lib.rs
third_party/rust/clang-sys/src/support.rs
third_party/rust/cssparser/.cargo-checksum.json
third_party/rust/cssparser/Cargo.toml
third_party/rust/cssparser/build.rs
third_party/rust/cssparser/src/color.rs
third_party/rust/cssparser/src/css-parsing-tests/README.rst
third_party/rust/cssparser/src/css-parsing-tests/color3.json
third_party/rust/cssparser/src/css-parsing-tests/color3_hsl.json
third_party/rust/cssparser/src/css-parsing-tests/color3_keywords.json
third_party/rust/cssparser/src/css-parsing-tests/component_value_list.json
third_party/rust/cssparser/src/css-parsing-tests/make_color3_hsl.py
third_party/rust/cssparser/src/css-parsing-tests/make_color3_keywords.py
third_party/rust/cssparser/src/css-parsing-tests/urange.json
third_party/rust/cssparser/src/from_bytes.rs
third_party/rust/cssparser/src/lib.rs
third_party/rust/cssparser/src/serializer.rs
third_party/rust/cssparser/src/tests.rs
third_party/rust/cssparser/src/tokenizer.rs
third_party/rust/cssparser/src/unicode_range.rs
third_party/rust/ordered-float/.cargo-checksum.json
third_party/rust/ordered-float/Cargo.toml
third_party/rust/ordered-float/src/lib.rs
third_party/rust/ordered-float/tests/test.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",".gitignore":"f83c74c38844f7e2adaf3f030f24945cf0f22e027b0bbf13fffb0057d6bf7ebf",".travis.yml":"38e73b40442027b162fbb1c86d9763b7b62f1763f7aa3d602f5dadc3e62e9bbd","CONTRIBUTING.md":"5e9b3fd8221769e98373298c880fe223d4655b57d58eb704bba375deed210f47","Cargo.toml":"5576d04ee29b29d662e1e28d510454366294e9ca71c94fc468654ad29d9baefc","LICENSE":"1d2e4bdb9d94ab020e9550136cae9ec73fc699c3c96a9d98078c542e9b93d294","README.md":"b0fdf3ed4ec467b9f1e4251935af3bdb7b1c5c585ea8d6cbd06cf2eb64107050","build.rs":"a6e333bda22a396c7c84761b63b4b6ee3ede6c505bff7776d076f96b1a627457","ci/assert-docs.sh":"48b0077b1bafba9a5fee4e19725e468a190445c79264cf9168308404a42d087a","ci/assert-no-diff.sh":"af208c40d412e2bce82ae9b4a4e52cae4ae0b4beef9f93eb825bf5d5346a70b2","ci/assert-rustfmt.sh":"b9c810e86ea6d71bce1d6bf8d896839cfe2c198338e042ebc744b75e83af1126","ci/before_install.sh":"4a3e31f387d55858fd8db2c88fea4167dbfc086ad59f81820da7665a80c893fa","ci/test.sh":"6b0beb98294af2cbeeefe22554b305df035574b8b01ff07bb3ff1cefc26260dc","rustfmt.toml":"c4f3b593bdd634590df22aaf7b0872244d5c2169aacd0274a05e4aca4708a8d3","src/chooser.rs":"a46aa29871b772a8d6bdcfb8c92b4e27c3dd54c3a4ec6a146fbe4e6883f58a63","src/clang.rs":"a86c92c9d80e968c019fadb4a7979de95f9978daf8244d9845bf459008a17719","src/codegen/helpers.rs":"910ba3d539437ef5559aba45a98b0251bf483d7481f6220c63aba2320f1d3fa0","src/codegen/mod.rs":"0d4533bea47034ac589bc50796d70c1ff5b35fd3dd94e425a598c5f7263c8f76","src/ir/annotations.rs":"887ad7beaa43eddd60337b67951a109c2e7f51cb8e757b35cad45f744b7ba919","src/ir/comp.rs":"2ebfc8edbb334bec11f01973ae1b4059b71fe5477b8070cc571e1770c3b47bda","src/ir/context.rs":"db71b77c7955ada702da29f9ae8923aa147c72e13de30319e5645f71e069b474","src/ir/derive.rs":"3593a370a8f56dc0fa1f1924b1652c74055bdbb22d5b20b9ed3493ba1d6bca74","src/ir/enum_ty.rs":"6e23e4828efe676f122b32ab82a6f41297ecfe1e08b728aa6165608f72da9184","src/ir/function.rs":"02c8998f11f6eb918b6b978e290c6d7bdca4d54caa50def4ecee167910c0707d","src/ir/int.rs":"dd467b79a642f8ab90b1316981e3ea7f29e697b7fa0f4d88c33b3a8f0f48bf4e","src/ir/item.rs":"ad7e0fc66ec2087ab07d3f5c9408bb6e808af39b41be068e45f39258277baebf","src/ir/item_kind.rs":"ad12a6dbea06fc61df8c91858d23114cbf56750c4307db51b3b16b0c982255de","src/ir/layout.rs":"afd0e0391ec4df042cefee99266d2ffb32e28939836f60020a8edf238b64e9f7","src/ir/mod.rs":"62929ebc2e90aae4799e07f6cb7bbf46da0da42475364e645a438df04baad460","src/ir/module.rs":"405af067b6947499952caa6b0d09ede8b7adf0e81c66ba284ad3b19aafcfbac4","src/ir/objc.rs":"a344052beff0df1f31882896be11ecd186b0b27ead1a19492396238193c40354","src/ir/ty.rs":"82e4ca6a42d7fa886a2136f5f9f98a3fa00fc4c80a8acb15d394e18ea4b695c0","src/ir/type_collector.rs":"1075f9a13ce4c7f938238e659d8e032592b7416709c20679dfe6ab2d0c1066f8","src/ir/var.rs":"34bfdeca239723ed962d5aae89738af1c364cb7fff03ead19f088fc2bf4e8288","src/lib.rs":"993a782b754cc0510479e1c8bcd5105ef4784412d804af31515971cb61e4bb79","src/log_stubs.rs":"e1e52b0b03397de90995afd5ddefc77e99eced2968c2203a393003435dbc436b","src/main.rs":"d02d3bfc812721991d4da77d4e8457b28693a59036fc76f86e7a42b50157e03c","src/options.rs":"d5288e01502a97d18264774b20e997da8cbe441afd57a2238c5e3b89692a07bc","src/parse.rs":"e7ea915a836e52d8d79043afebd0c694a7c44b0cfc530d2601d242febb00ee4c","src/regex_set.rs":"bb77bf0afea3e00d8174b98fe915b3dfd921859a4360077f39722a63582b6da3","src/uses.rs":"872c23f4cf2ae8e51b558853caaafa79eff0eb12a2981243612fbaeba855e48f","tests/headers/16-byte-alignment.h":"00d82adc7f58a875da5f2be2d3d5104e30528e2c6781f268c0eb912d0b152f94","tests/headers/381-decltype-alias.hpp":"c956638f898232c46bd75851ba9d6937b8586a907dca947f64c64bc216d18cbf","tests/headers/accessors.hpp":"7300e99f0bdf614af462a6e9c0bbdd01d5f2053c96bcfe19d55e3f9a078cbe0d","tests/headers/annotation_hide.hpp":"128644863239b73c5ac0c18aeaeb3f3a791feac10b53ff15d044bb83f0789b61","tests/headers/anon_enum.hpp":"dd5bf5a3959b73eef283c861b72e391961b37378ff130247ef62807a6973446d","tests/headers/anon_enum_trait.hpp":"2275f9c070ed690ec48947779fea0d8f7102121abcd3a80865869090310fac90","tests/headers/anon_enum_whitelist.h":"723fc9f71a353b6b40c5c418c8d1ac7d064f2eb160e204e8a7d3e41092a063e7","tests/headers/anon_union.hpp":"67ec069c869a293225e4d70fb8736c00439da092a551e4e5d674454a51763e8d","tests/headers/arg_keyword.hpp":"e100654db2124fb95d3dd139f4972f1f4b3a295bf5a8a48d374a43266a687325","tests/headers/auto.hpp":"612feab94728cf4c8e99aa8564afbed9be4aa4229b682e3da98eea43c6aee604","tests/headers/bad-namespace-parenthood-inheritance.hpp":"afb9098bc986809839817e5c3e9b58807d3998a110873910690b3107b738b774","tests/headers/base-to-derived.hpp":"82225b95e38cff09cea3d2f553cd336d854285dd20f20f75c023ecd00823cbf1","tests/headers/bitfield-enum-basic.hpp":"9a46e1ab84a5b1fa166f8bf7d6385c322a970d244ecf39656606a5e3a4d90e01","tests/headers/bitfield_method_mangling.h":"ae54e014be753a5a38f7b878120cf98ee051693a167283256a55307fc4eb07fd","tests/headers/blocks.h":"9a66d2119f8d08a9788f341a6abcdbe94aa1ae76936141cb5b89b4fe77f4e284","tests/headers/canonical_path_without_namespacing.hpp":"78e7937a13dd17fa8f2467bf226540ed8e04ec721d98c327636616d3be0610fc","tests/headers/class.hpp":"9f21fb226eebc789f50a06123c4abb2886130f00b658eecb7c6c95a2b561855b","tests/headers/class_nested.hpp":"645265163e897bd51ce12876a779808ab2abca82dd4856fde287abf837bd53f6","tests/headers/class_no_members.hpp":"c466313e6157f567e62fa1323dd4243bdc9ee3bf94ef43f599f5ba612e074961","tests/headers/class_static.hpp":"8bdd7d3b31722cba32af72b7a5d469b43ef69ee710fc80127de8262364ac8ab6","tests/headers/class_static_const.hpp":"cf7860a7f1649300a1ae4e294847187cb4a01c4b7d4108cc9dd8b37780d137b5","tests/headers/class_use_as.hpp":"c9f8816493461046fcafc494c6a51a6c7871f65f5ecb1bae6cf5c6a45d83635c","tests/headers/class_with_dtor.hpp":"1ff087a703278628f7954f93d58e72e5f421540936ea341035d244e1a98ae503","tests/headers/class_with_inner_struct.hpp":"4191f3bd5dfb778aff73beccd4e3fa5a578bf9b825e90114379cf6fb1fbfc676","tests/headers/class_with_typedef.hpp":"697bb7a0f2b0dac7e5552b5567bd13e90e707e14a5901cf32bec9642ba991bf9","tests/headers/complex.h":"470b172b3980c57bb1bbe2df9562083749716b7345fd1543a715c101f38e6964","tests/headers/complex_global.h":"e8d9de67b33a73120ffa3ef676e24def347834f2567e75fa967da8917ca05e5f","tests/headers/const_bool.hpp":"e147050b90b28f261640dc9e19819b9166f943dfce3a1101a71066f8a13230d6","tests/headers/const_enum_unnamed.hpp":"e5dd66225fc721943dd8706f930ba9dc04c9e9a535c9d2b70215e563eb23359c","tests/headers/const_ptr.hpp":"f55a4a914bf4cde1c9be63a99ea58acd3a4d6b722b9d6b4d570de91aa90a861d","tests/headers/const_resolved_ty.h":"572c999b6224bdb34fe807d75f27b49c9ca5d737150bbdbc18a4fdfa4c00ad1c","tests/headers/const_tparam.hpp":"32101adfd9b408ed29ebe330219cb66da199d194c54397cf0a6a51bf40d5770b","tests/headers/constant-evaluate.h":"f1f3dd8a07f7e45ad46ae1801406b989f3d731294149520675ddf4a7dd262766","tests/headers/constant-non-specialized-tp.hpp":"48cdc56a5689e1c7d8ba2bbc0f606b3f7a9b179d35b461d2afc3c41398b69c7e","tests/headers/constify-all-enums.h":"e6756535ff5ff68c122a0c40e621a61c968e6870128d9002d77a0f59d373aa3d","tests/headers/constify-enum.h":"f6fc217be7558f4cd25c6f7b7286f99e5124596364fcf0167133fcbf66377292","tests/headers/constructor-tp.hpp":"4d7e4e7f8642e2341679c84bc36eb609fd257b5475ad5ca216ffee974297e94f","tests/headers/constructors.hpp":"5ee56a7b05b71dc55bb9dfbf8816b5045142dc22f1c6d286319a6d4653a4984d","tests/headers/convert-floats.h":"b771a2ee9ed87b132494315b7a48449f783d903e96583a7642e61785b60d576e","tests/headers/crtp.hpp":"5ad7d00d2cbf243a89a8935eab5ab2997d7e828cbd54a5699a56064a37656152","tests/headers/dash_language.h":"acccf995806466b4f7ed7e4ef454ca1c8e849011a2bf52e5825a29ea52e01133","tests/headers/decl_extern_int_twice.h":"6ed5703307ac0712871a0e2e4cab19ebf26e3114e06b495274031376ae4027aa","tests/headers/decl_ptr_to_array.h":"76157bc1b4650bbec96ae52d672d42b71d0d0a16dbf9edc24b9e19d3e9d0ee52","tests/headers/disable-namespacing.hpp":"35e390e7aa60d675b2fa6a1737a48688fdcb05c7d2dc5506a5cd1d00a64bced6","tests/headers/duplicated-namespaces-definitions.hpp":"2940fc83895551c01969bb23432df847443fca306e26d9fb1bca8483887a3d23","tests/headers/duplicated-namespaces.hpp":"18b9fbbdbdea4952aaf0e308a95ba9453b92dc2b7e0c28e2175d8d9fc4db3c10","tests/headers/duplicated_constants_in_ns.hpp":"c3d2950b1e105c8c6ddd419999d20352ffd7d0ded0243cf14e1651dbf87adf42","tests/headers/elaborated.hpp":"d818eb9d298fc296fd35ef50e1b10658a66327748ba568c2b3e1e88e52651391","tests/headers/empty_template_param_name.hpp":"c9364c8a071bceecc0d6e4a764193a5cd653f688e9fbf543fff57b4263f0305c","tests/headers/enum.h":"513c9462f908150540fd4c31cf486c4e855b8b690786b02aa62ec86f969b637b","tests/headers/enum_alias.hpp":"684150ee62e3a1c9deb169c76bf32ac907751fc667d0a8ce8c2715371021c03f","tests/headers/enum_and_vtable_mangling.hpp":"dcfebe04ad23eb146f43ce3912aceb3170dff62552808cb7ce069946dc7868b4","tests/headers/enum_dupe.h":"d8c3ccd7155412ba5cc1cd37e0ae0005ca8460e570f5a8d8d7318615f19c264c","tests/headers/enum_explicit_type.hpp":"6295f549659449d977d451d6c07046af23309e8ac7d8be40c335f2fe79f897e1","tests/headers/enum_in_template_with_typedef.hpp":"6a1c37c7464b6ceb3916893698420cd339e55be17bf546381d5a4e020921c148","tests/headers/enum_negative.h":"9ddbe83fab84947ad2b8292a722ac7f5c3e1bfd1d1ad1ce08434ddee52f0e338","tests/headers/enum_packed.h":"1c8b49061675f9cf83c429eccc63725631883832d7e5ab30554accc6db7dc09b","tests/headers/eval-variadic-template-parameter.hpp":"d9190b6b7f96f678206c328161617d847e53b7356833c7ca32fc7ed4dddf6dee","tests/headers/extern.hpp":"68f1eba8b60316cd8bf52731a5dd29c84559342e7b66daffe6b769dc98f837ec","tests/headers/float128.hpp":"f0a676919df69373828a2a32f10b3b22a6c978c08864099603b10ddf444c26b7","tests/headers/forward-declaration-autoptr.hpp":"8c808baeac1af6c9e3efe0ee78d9ca76580502c713621e3f6ad2f298f0808bd8","tests/headers/forward-inherit-struct-with-fields.hpp":"3d63ec1d66bb080c4617fa945890cf70cf02f2af7b190e6a28fcf196fc8ea1f6","tests/headers/forward-inherit-struct.hpp":"c3869d51ecae6ff5ee6bd5d6f9710be60f93aea09e73d9b97a6c9068eb94e4de","tests/headers/forward_declared_complex_types.hpp":"deba01c271881fb324170c78ed26d37904cf6da0185b1d4472a9e3354be024ae","tests/headers/forward_declared_struct.h":"e31acf91e4d112e31bcba7040f2a1366853b442c52b9b04a40c73e0f2903bfe2","tests/headers/func_proto.h":"bf9519b408ee057b71bf72ad4ce910a5b75a15ae8daf12f536b65f9f9478c461","tests/headers/func_ptr.h":"9723273d527c1be57d6517cf8123e424225cd9d25a801f42618395ab5258d2fa","tests/headers/func_ptr_in_struct.h":"ce517145afed4eb8f9d14233248bc479a88a2fdcc52dc23029c498aa306f129c","tests/headers/func_with_array_arg.h":"1f6fff4283d90e96ba44dc7c64a778ad5e725fbf8167f04697bca20176eb6d2d","tests/headers/func_with_func_ptr_arg.h":"938475e53aafa207ebef7f4a84a9ec009d8dc4fa258fcab446318f5b0f1cc07b","tests/headers/in_class_typedef.hpp":"3bdc8ad6b9013b993dccec2d1bdec69801062fb41e251790bb5f93d89a562bd0","tests/headers/inherit-namespaced.hpp":"7636ac3a56620b20a8991b1a6d228fda174cbab02ddfb3117163700d8514fa55","tests/headers/inherit_named.hpp":"3fec93dcb2359d9acfb284acc39f7050362d8ecf05d828eb20eeb81d96f98f3c","tests/headers/inherit_typedef.hpp":"3ca1a4993c29282a18a0ba72186f3297ae26efa32cf22d05c1613fc799c9c466","tests/headers/inline-function.h":"028efdd98df34a85d9631357e95e7a6809ef6e8206ab3c00ad5181ca88826aed","tests/headers/inline_namespace.hpp":"ac8c6091fe3611877918ddfcf8a02934497ea4291c91ade237206f67fafd5cfe","tests/headers/inline_namespace_conservative.hpp":"820857eac505fc4bb3e5ba76d8cfc358d84b737ddbf99a2938522ee0fd59fba7","tests/headers/inline_namespace_whitelist.hpp":"6372a42e6c419d7e096b6fad3636d4076080951b6078120fa954869fa40c7b15","tests/headers/inner_const.hpp":"7325eb025bf4923ef4f8df164037d9398895b36107a1ed444bdcc5b419a56747","tests/headers/inner_template_self.hpp":"3a356ef1a1fefe9ec891bfdd9f2341b8094246caa2bf9fb321a6b061069f84ac","tests/headers/int128_t.h":"f460a6823e171a42be7bdcc6d7212b2821b01b8b887e3055fc6484a59f050789","tests/headers/issue-358.hpp":"4abe91b5721875d99c4102b174400b1ad365ea82f7367a6266c5e6dc21e26bbc","tests/headers/issue-372.hpp":"9ecf1029c04e3ec7462416a422172360c0a3ed5eb99a1536bafb5e3264ce23e9","tests/headers/issue-410.hpp":"dff6dbf8763017d35ab103ce15c19c9aa3ce61253dda7b8e313238b30214be68","tests/headers/issue-447.hpp":"e96fe1ee3215196413903c0d2e63b53352c8d83077f661edf5dc5b257b2cb0fa","tests/headers/issue_311.hpp":"b25e14cfa72cd5425f2cadfc0868d2bcacf6ac4c019945a840d19d7bb1811a67","tests/headers/issue_315.hpp":"6ebb5e7aeded8cf9b63f25478445432f8c76af731f7d587cff9932167fd32a75","tests/headers/jsval_layout_opaque.hpp":"5a82a83ee9e27d67641ad2805d616ea02a9828c4ab31aac9a08710f6b9f70b87","tests/headers/keywords.h":"9782ce81a46a25744ffbcf1970c0944f7230b9967085c3181ee3085ca7b2b2f0","tests/headers/macro-expr-basic.h":"bce59cdefb620457295199dd7b2839e1e397292d9bab10d54b5360b0574b17d6","tests/headers/macro-redef.h":"a5b95e2b26425119c567f45bfc3ad7d298c2efcad0132e9a9bfc3078dd0c4bcf","tests/headers/macro_const.h":"ec5c8d2009ad818c0fc242f76eaa8d3562633c50e50c0444fe293b3f8ed10ef0","tests/headers/maddness-is-avoidable.hpp":"8ba98872bf4292d014729e7b8248e750412a75cebdf2edbb684173aa0db7cf87","tests/headers/method-mangling.hpp":"b7ffe0e3b002bc032fab6b7785b03e635c0595bbc03d73fae4164611473dae2a","tests/headers/module-whitelisted.hpp":"a88e2a3e2f0f3edb205e60f9b08f4b1f7e017c15dc12e0541697006ba947025b","tests/headers/msvc-no-usr.hpp":"2b11fc139685e78a11bc224967360cb06f768b09e033a8be01d97002587383d9","tests/headers/multiple-inherit-empty-correct-layout.hpp":"7559184da00f812c7679bc5a863e5720447bd2b38a42310a2ec3114f405398a0","tests/headers/mutable.hpp":"cb85dc019dcf866ebf4e092d5c6ace509957c64c18eb48ccfb7b47116bc06c2c","tests/headers/namespace.hpp":"c0417b68013beb38ce781e385d0c7125b895d75e27a07ea6f05209050b9b5a19","tests/headers/nested.hpp":"0f56cd4d50004a75d8b54226f631db939ad918b7e68d48d4ebaaaab7dffc5eb4","tests/headers/nested_vtable.hpp":"c1a7f59161dda9429ccd146407a3899a27b1749c2feb4edf5537fe912f7f423d","tests/headers/nested_within_namespace.hpp":"841c9aae50dc4303e468878514939562870dabb94da909c82fa19bb2a35d1bfe","tests/headers/no-comments.h":"6dc35a97a702a99f43ac716dc6879137600b7f88961deaa7a148de505b3c2b4f","tests/headers/no-derive-debug.h":"69ea2990e44fc7d22499f672758b03e445bb08bd76bc0f5ff52ad51cd1ada1b0","tests/headers/no-recursive-whitelisting.h":"5153922c341e809cab973c5def7c503dc9c69d28275e0a30255fdbcc51c4210a","tests/headers/no-std.h":"3b7b5fabdf51588a48f11ff8a6961b652b4251125db45a32fd743a973ed929f4","tests/headers/no_copy.hpp":"b07c1dbc2f70aced75cee5421e78a1501cf6193508169c966394d86521b5c6bc","tests/headers/nsStyleAutoArray.hpp":"a80160e314377d8d5083165e9fd42e2e5ca31b211afca51b4b0e761f41e40824","tests/headers/objc_interface.h":"5a6ebe82a544b81e9dc75b9e11f03b8b5044758c0c2d0e43dfb0900602544f24","tests/headers/objc_interface_type.h":"b9831168069a724518c5a3c972271a8e82e9c74ea2f993ae9974a18c4a89ec5a","tests/headers/objc_method.h":"0259b190ff4ade0e5df539878e6942c71871e0c57b6d10256f450284653e8bd4","tests/headers/only_bitfields.hpp":"bc9e1be2d946e5ac4116fa000c55fcbece500e98425404fc9d3b0cb9726ff7ba","tests/headers/opaque-tracing.hpp":"bf3326089c275be21b336cd4fb7ee5456d89c8444265daf49c3c5440b30f4264","tests/headers/opaque_in_struct.hpp":"31907f11d4b2d6fab2871b0d3314d2a3f5ebff5acae37f1071b5efd8090f8d58","tests/headers/opaque_pointer.hpp":"a7f97c2e2a6ef6433eba296b62d176568daa1383201631dbbcf081775b7a747e","tests/headers/opaque_typedef.hpp":"204404343f0050f8028678555ab6624777c678ce69ddbb9f54552011ea4e1a38","tests/headers/overflowed_enum.hpp":"0d927f0366546eb6459e5c81fcdd497ae8ba113ddc039af79847f0a05281a835","tests/headers/overloading.hpp":"2f0e0f44a6b1a7c4a72ab9e33863568ee7d24d2a271a701739aeac82c2d1ecc9","tests/headers/private.hpp":"2eae7fa2dd83fe3607e291746b3025b1e4265a0e1e584013fbea41fdfbd91725","tests/headers/public-dtor.hpp":"ed884a9c93569d1ad98c0af942dfc5f65e7cc67f579b2d1e6f940f25d4864f7c","tests/headers/redeclaration.hpp":"e9fc6785054ac6f6d4574f1846aefe933b09e26d398bd4cb47dad4ab8fb524ff","tests/headers/ref_argument_array.hpp":"c70b8b9ca935e2c9d0e78075f66220b33960fc4244c642d35cfcbe3c585e4371","tests/headers/reparented_replacement.hpp":"4f7a9cf64897155795abb0a55be2fde6512ff2108d7b3fd2495194efb2e1ca43","tests/headers/replace_template_alias.hpp":"982e0d2b7e6b9a7df1aa34d89df2520cc5d6b2b9c16f56c1369fe0ca3a88cb18","tests/headers/replace_use.hpp":"5bac44653be912b5af5062cfc4561e30cfcb7f91d321f8a6285656e2893cc349","tests/headers/replaces_double.hpp":"be76785b1742d8c2ae7011b230dd11e3c9d1b3b8218c2a76e4fe73c2870b5e80","tests/headers/resolved_type_def_function.h":"e080509e0cea0eb09262113b0f90d147928ffdd9a7cd9c3158628f5df5ecb426","tests/headers/same_struct_name_in_different_namespaces.hpp":"90a923bf707ef9de241cefba6397c088b6ffbad5ca7c997c4460af3876fedd04","tests/headers/size_t_template.hpp":"7e73bedf712c9f4b80f6e7f5e1411b91e01a3ea47bf2d261550ca785aae0c912","tests/headers/struct_containing_forward_declared_struct.h":"c66f635e39ee5b8fda94e9499b2fd682181ab819728ac268aa2ec40b62ac0e13","tests/headers/struct_with_anon_struct.h":"4ce9c56a41b2fde0ae0062e5c87315dd69adc3ef79575b267256f47a9bd531b1","tests/headers/struct_with_anon_struct_array.h":"cb13830919d4039fd8a64b5aa972c05c21f5bd5d1f8722aa865bcd394f9f3c0c","tests/headers/struct_with_anon_struct_pointer.h":"4e0b669af481100125bd0bf1a4e17bd9ee1e03fb6cc8ee36875d71ecf6d63adb","tests/headers/struct_with_anon_union.h":"542567e8d54e51f43eb6699503d857fe5177ecd51b6ad5d5667a4992aa438f28","tests/headers/struct_with_anon_unnamed_struct.h":"0ae74d3b11fc64b30fed7f217f0cc51488c93b88a62755628699affdeeb8f5ef","tests/headers/struct_with_anon_unnamed_union.h":"71c9fa48a80fa5ee3714f76eb4faacae096f30ccaacbe51e8099760abf601aa9","tests/headers/struct_with_bitfields.h":"f8faa67dc47a88b0bd0b45d42ea170a714a67f0ef90b6f2e4870006bb499fd21","tests/headers/struct_with_derive_debug.h":"c4afb2aa9ae08b2e55270118f162cb611f011a64fa5b37e87aba7efd6a515a9b","tests/headers/struct_with_nesting.h":"695cdad138a59713aeee75050a8cf6f19bc1c16af7c49bb65e7a1fd6924e549a","tests/headers/struct_with_packing.h":"409c1b58233f45f65d4c6dc9bc233feea13549630b7267a320635fff0afce563","tests/headers/struct_with_struct.h":"f1d2c84e45396a4f5c16dbdd2db59d8bd4004d24e9287387bf55d532c7e4820e","tests/headers/struct_with_typedef_template_arg.hpp":"a620d87c5138d8b24842cddf906a00b2c74a95ee68d67d3b25a993264704f62d","tests/headers/template-fun-ty.hpp":"c0724925f55650d20f1feda29cb5f10758000a4ff5ea8629f45cd90442b5e651","tests/headers/template.hpp":"92517022906ea22b58f8edc58f4b2cf438e586c8b34b9b24f5a93f509fe6c45d","tests/headers/template_alias.hpp":"1df4a71f910aca9e6971927d48927baa777782e8a24c3880a68f97af41bb17d3","tests/headers/template_alias_basic.hpp":"676cb84ef33cd1ea7c0d4490304cb5f8d26f792035970aec6a81a1bed5fbdbc7","tests/headers/template_alias_namespace.hpp":"49e66046de03ffa6c00713cf184f80eb5182284b43bfa4457bc8657e2504ebc6","tests/headers/template_typedef_transitive_param.hpp":"6c6ff83e79eb8c882f6fc8340ae3e21727205dbea882e9f7092ed1127775967d","tests/headers/template_typedefs.hpp":"12b5892aadbe8529e7fdecf2956f9e276824818ba6f3fbbde41cc5c7e628337a","tests/headers/templateref_opaque.hpp":"6ea0675c05821e4cd023e6541d8e33d6e762e1b30e55b1aa4f81360dcd93d324","tests/headers/type-referenced-by-whitelisted-function.h":"40ea5086de6ca2219c18db7b32846614737405eea8a3c3d70b198f1b1475d281","tests/headers/type_alias_empty.hpp":"f28175e7b5b843bbb35fe6214f0834ce9c8e6d0da52432cea252e2ed9a1c7d3c","tests/headers/type_alias_partial_template_especialization.hpp":"8c21d219cca03735d2a94bc0b9e9ecbee781d8c1655bd9caf7bedd51a6b77e95","tests/headers/type_alias_template_specialized.hpp":"15ceec92f8ccbacae71d7c8b59ecd8d81347cbcd0b4e0ed4366f17bdbbe95f1d","tests/headers/typedefd-array-as-function-arg.h":"7069fbb775a6b8af548ed0de2d24f3e2e35e10ebf8eed3c8841a220f58efa10b","tests/headers/typeref.hpp":"e314362ebff945a823b4a65bcd4931aaee3f93bc50baa57771da15fbf36c0b58","tests/headers/union-in-ns.hpp":"adb1d203918accd7177e55dd97ee64d1e908403c1e5c8c8f9ba4af5f50d6e522","tests/headers/union_dtor.hpp":"4ce6c54758690778348f84f8a876b8d0bb9cfecec95668147f815bb13d57d801","tests/headers/union_fields.hpp":"4f91a0013e39abbe0e10667f72ae902441ac2f1d9245c79ae182ae606794ceba","tests/headers/union_template.hpp":"142a263ee4db89573dade811057b0e5a4e0deae61c6859612068ebb5edd05503","tests/headers/union_with_anon_struct.h":"201c566f923d41e2b9cbc788f22d084e480d73ae1be9eed7096f1bac2870a034","tests/headers/union_with_anon_struct_bitfield.h":"2a7396f341ec34fa82f4705b3867d8546cbf8d2e62e790a70169bd807a70c8cb","tests/headers/union_with_anon_union.h":"5634be743d250fbfdacfc07a3bfc3b4d7659e8e201d0801e2d956aa0e1350a7e","tests/headers/union_with_anon_unnamed_struct.h":"5df9ec8170a3f712757a1000cc6f6883b95506dcaf8c94c59f03c7f26d3cc2df","tests/headers/union_with_anon_unnamed_union.h":"563f09841597a93f956a75db20261b8a9d290d88a385be343c6bc4cff6ecd66d","tests/headers/union_with_big_member.h":"d4622757fea8ff6ff7fb67de83e0e2511b078d3a74769bb847dfe1459317e5fe","tests/headers/union_with_nesting.h":"8e800c0fc5449d2317b51ec8a3e39e7680b7b0f29d00fe917e6c9d6da3854f0a","tests/headers/unknown_attr.h":"f65c88592a105bbbe3bd98bd46b15ea7c2cc82dcf9fbda6eceecc9c341228bf3","tests/headers/use-core.h":"691b075c045236aeb38b06755519f823f2a86ddf1d567f12887b240aeba6c813","tests/headers/using.hpp":"5021a2a1ff4eaa6dabf5dd914a71357562d4a81573d2680342a3b193e9951496","tests/headers/var-tracing.hpp":"8b93ed99969a7a32ed1e49c52df77eee4ef077db758c0f58666c46efddff3adf","tests/headers/variadic-method.hpp":"9947eda68dfb6ddcd59b558f2fcdb2356bea27cfa9f22c6a46114ee937fb88b9","tests/headers/variadic_template_function.hpp":"232d2112a60f18e5704b64df573e814f91e45dd4d7be14d8b00a11ef436ee042","tests/headers/vector.hpp":"0a80c8886beaa6a9fc83e6652be26be1e6b23e1db006111a45b2c8a7f98e7dd1","tests/headers/virtual_dtor.hpp":"b1a3928a25c62d51d394e2192f91e250298c0357330241609103329f43185ae7","tests/headers/virtual_inheritance.hpp":"d92e8a26a939e9a7d575f3af0caf3081a30b3409f6f320432e13719cb7ddbad1","tests/headers/virtual_overloaded.hpp":"fea58d5f4a1814f7907e0066d1019e334ae0798454448eb825fb3f81dafd1a8d","tests/headers/vtable_recursive_sig.hpp":"5aae5edd330622207e6a803ad880b421d1530aa81fd57b8e10fe7faca186bd01","tests/headers/weird_bitfields.hpp":"86d0c0ddd64f812874889f21c395df49001bd91b114613c650806d46da0063b9","tests/headers/what_is_going_on.hpp":"8a7ccdcab365c12f176114a223da9aba83ecf6c98f349a56b74579bd0d9128ee","tests/headers/whitelist-namespaces-basic.hpp":"fae14a96e1d7fc9a32972d182869f0e64ff098ab7a9596bfdfd1ab14c7eb3950","tests/headers/whitelist-namespaces.hpp":"22c965df52d5641a16588eb8d718f523ba7fb16fed2f0a13847abcd78786af9a","tests/headers/whitelist_basic.hpp":"f63a40850cbf2cae91e804f89df184bfc352e222e6256c3c7055950d0c5d0fe9","tests/headers/whitelist_fix.hpp":"19f34cbdd375a43709fb73786814eccc5510ec902d5d645d7550dd4e70c5d9e0","tests/headers/whitelist_vars.h":"926f3437b49cb7434a0c9964a60182a4fd4ab29c25217621ee3510ab5e9ad282","tests/tests.rs":"bedf9bfcfc8910502f09af2ca78ce1daface25e859e7ff7b7bc463c6fa504998","tests/uses/.gitignore":"377f40a9357416f0d0063605ea555bf4c876bf0adeec4e5093654c9427efe7d6"},"package":"9cee948f9ad10626c930b6f8651d53534c00dbb1243c36cf99576be2554f332b"}
\ No newline at end of file
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"f83c74c38844f7e2adaf3f030f24945cf0f22e027b0bbf13fffb0057d6bf7ebf",".travis.yml":"4f88383d548759360597a231194c9b6cf7608797d3abce7ac62ce79280c025f4","CONTRIBUTING.md":"cce77105e6e440bd3a3a10598574874f969bbe6f00ddccfd263232c44b74593e","Cargo.toml":"d9f3acb1457cd69904bd23258be7294d208993e3caaf1724630ce191810cde83","LICENSE":"1d2e4bdb9d94ab020e9550136cae9ec73fc699c3c96a9d98078c542e9b93d294","README.md":"b169983c6ae5ffdc4bafe2ac4e8cb0e945f2cb0d3ba99600febf18e481cb5734","build.rs":"e6ad8262fd49449da3ff4328a911521c05a31e363475147e22f1b4cd9b72cc06","ci/assert-docs.sh":"48b0077b1bafba9a5fee4e19725e468a190445c79264cf9168308404a42d087a","ci/assert-no-diff.sh":"af208c40d412e2bce82ae9b4a4e52cae4ae0b4beef9f93eb825bf5d5346a70b2","ci/assert-rustfmt.sh":"b9c810e86ea6d71bce1d6bf8d896839cfe2c198338e042ebc744b75e83af1126","ci/before_install.sh":"4a3e31f387d55858fd8db2c88fea4167dbfc086ad59f81820da7665a80c893fa","ci/test.sh":"6b0beb98294af2cbeeefe22554b305df035574b8b01ff07bb3ff1cefc26260dc","rustfmt.toml":"c4f3b593bdd634590df22aaf7b0872244d5c2169aacd0274a05e4aca4708a8d3","src/chooser.rs":"6736ddc28567c8a31cc7b9508f45c2adb19ea69eac3e5a9a65a71d39cf46c534","src/clang.rs":"bcf5f88669276e70814d31ffcbda6c0baa9826c63459ef3af4cb64717973c10b","src/codegen/helpers.rs":"910ba3d539437ef5559aba45a98b0251bf483d7481f6220c63aba2320f1d3fa0","src/codegen/mod.rs":"12c79aaaab2fe577414c95f726710bd21c6a208b90437cfbfebc84a0929772b0","src/codegen/struct_layout.rs":"d471f0119fcf24f38e85a8491825c3196c5caf0df363209aa369bf934d34d796","src/ir/annotations.rs":"887ad7beaa43eddd60337b67951a109c2e7f51cb8e757b35cad45f744b7ba919","src/ir/comp.rs":"12a4cebdeac91ae40a1c6c32b56cd63e5a65f3cd24cfcc9f559e1ece5b1cb3e2","src/ir/context.rs":"9267d36fdc463009493acf3211063212ee741db8c347c09da9d24b4dcb23f785","src/ir/derive.rs":"8706a8e3c4ccd2135d0eb9ec8c0e02008609604bce42cad2974f3ca7d2ca7d91","src/ir/enum_ty.rs":"83b74b9ba9b9ad3269792f74eba9c1358cf259f4be65417e4b4e19507f1251cb","src/ir/function.rs":"b026f935fe56aa997547412663a192227ae4bcdf2d41563efeef09154e5e910a","src/ir/int.rs":"dd467b79a642f8ab90b1316981e3ea7f29e697b7fa0f4d88c33b3a8f0f48bf4e","src/ir/item.rs":"8650d88b72ce5c7e87e2b3b3526a5b1752131ece0a6258f3ab75b9e121adf0f7","src/ir/item_kind.rs":"cc4acf0328dd94e2cfc81c3f1d4ab2549c66a934ad59fd647738c7e618b78c11","src/ir/layout.rs":"83f1b5dea286281e3c3eb0d8b7a665f17b224d8355f52f32ba3145a5c41bb4ad","src/ir/mod.rs":"27888851ee092c36158e2dccc90858cee7d9285dd9b3dd521cfa16eb19a74a1e","src/ir/module.rs":"405af067b6947499952caa6b0d09ede8b7adf0e81c66ba284ad3b19aafcfbac4","src/ir/named.rs":"0dc9a82a7017716a78d29e81eaf271ead8540b433de62129f86107105ea8566d","src/ir/objc.rs":"3987c7211ccd0480e33879405301da1ff5de814eefb8c2627a1c888540d81df8","src/ir/traversal.rs":"1d23d5c64a4b208e95bbefa5f922e7554590e22ca249b0678b88c04dfb1dcc24","src/ir/ty.rs":"8c7378be1375512de5390626e916c12709fa6d64c15dbb376ab4eb17f4ef4cab","src/ir/var.rs":"34bfdeca239723ed962d5aae89738af1c364cb7fff03ead19f088fc2bf4e8288","src/lib.rs":"c1febb40fa715ed68edb3364ed8ec647915b295cd9b93300042ca92bdf195905","src/log_stubs.rs":"e1e52b0b03397de90995afd5ddefc77e99eced2968c2203a393003435dbc436b","src/main.rs":"3ebe9d8dbcaf981ef8f84b5616f74ca9c9e55a1d6aad94d86546d3444cc44ab0","src/options.rs":"b9e33f4b8a1d5cea456bbaaa1e4ee54930426c6312ec4ece9f07c0a573bb94d3","src/parse.rs":"e7ea915a836e52d8d79043afebd0c694a7c44b0cfc530d2601d242febb00ee4c","src/regex_set.rs":"bb77bf0afea3e00d8174b98fe915b3dfd921859a4360077f39722a63582b6da3","src/uses.rs":"872c23f4cf2ae8e51b558853caaafa79eff0eb12a2981243612fbaeba855e48f","tests/headers/16-byte-alignment.h":"00d82adc7f58a875da5f2be2d3d5104e30528e2c6781f268c0eb912d0b152f94","tests/headers/381-decltype-alias.hpp":"c956638f898232c46bd75851ba9d6937b8586a907dca947f64c64bc216d18cbf","tests/headers/accessors.hpp":"7300e99f0bdf614af462a6e9c0bbdd01d5f2053c96bcfe19d55e3f9a078cbe0d","tests/headers/annotation_hide.hpp":"128644863239b73c5ac0c18aeaeb3f3a791feac10b53ff15d044bb83f0789b61","tests/headers/anon_enum.hpp":"dd5bf5a3959b73eef283c861b72e391961b37378ff130247ef62807a6973446d","tests/headers/anon_enum_trait.hpp":"2275f9c070ed690ec48947779fea0d8f7102121abcd3a80865869090310fac90","tests/headers/anon_enum_whitelist.h":"723fc9f71a353b6b40c5c418c8d1ac7d064f2eb160e204e8a7d3e41092a063e7","tests/headers/anon_union.hpp":"67ec069c869a293225e4d70fb8736c00439da092a551e4e5d674454a51763e8d","tests/headers/arg_keyword.hpp":"e100654db2124fb95d3dd139f4972f1f4b3a295bf5a8a48d374a43266a687325","tests/headers/auto.hpp":"612feab94728cf4c8e99aa8564afbed9be4aa4229b682e3da98eea43c6aee604","tests/headers/bad-namespace-parenthood-inheritance.hpp":"afb9098bc986809839817e5c3e9b58807d3998a110873910690b3107b738b774","tests/headers/base-to-derived.hpp":"82225b95e38cff09cea3d2f553cd336d854285dd20f20f75c023ecd00823cbf1","tests/headers/bitfield-enum-basic.hpp":"9a46e1ab84a5b1fa166f8bf7d6385c322a970d244ecf39656606a5e3a4d90e01","tests/headers/bitfield_align.h":"df403e1c2496acdf42a3be669043a1f70d0ab3e47ed5ce4f5dad983973499192","tests/headers/bitfield_method_mangling.h":"ae54e014be753a5a38f7b878120cf98ee051693a167283256a55307fc4eb07fd","tests/headers/blocks.h":"9a66d2119f8d08a9788f341a6abcdbe94aa1ae76936141cb5b89b4fe77f4e284","tests/headers/canonical_path_without_namespacing.hpp":"78e7937a13dd17fa8f2467bf226540ed8e04ec721d98c327636616d3be0610fc","tests/headers/class.hpp":"9f21fb226eebc789f50a06123c4abb2886130f00b658eecb7c6c95a2b561855b","tests/headers/class_nested.hpp":"6363341c6d4ce7ebe3f1d188c02c61a139e2f28508ece4e537912b52ee5d6e1f","tests/headers/class_no_members.hpp":"c466313e6157f567e62fa1323dd4243bdc9ee3bf94ef43f599f5ba612e074961","tests/headers/class_static.hpp":"8bdd7d3b31722cba32af72b7a5d469b43ef69ee710fc80127de8262364ac8ab6","tests/headers/class_static_const.hpp":"cf7860a7f1649300a1ae4e294847187cb4a01c4b7d4108cc9dd8b37780d137b5","tests/headers/class_use_as.hpp":"c9f8816493461046fcafc494c6a51a6c7871f65f5ecb1bae6cf5c6a45d83635c","tests/headers/class_with_dtor.hpp":"1ff087a703278628f7954f93d58e72e5f421540936ea341035d244e1a98ae503","tests/headers/class_with_inner_struct.hpp":"4191f3bd5dfb778aff73beccd4e3fa5a578bf9b825e90114379cf6fb1fbfc676","tests/headers/class_with_typedef.hpp":"697bb7a0f2b0dac7e5552b5567bd13e90e707e14a5901cf32bec9642ba991bf9","tests/headers/complex.h":"470b172b3980c57bb1bbe2df9562083749716b7345fd1543a715c101f38e6964","tests/headers/complex_global.h":"e8d9de67b33a73120ffa3ef676e24def347834f2567e75fa967da8917ca05e5f","tests/headers/const_array_fn_arg.h":"66c97fb3dead550a6eb69d449a90df0b84e3daf0f7e260e3c23fe9bce54199b4","tests/headers/const_bool.hpp":"e147050b90b28f261640dc9e19819b9166f943dfce3a1101a71066f8a13230d6","tests/headers/const_enum_unnamed.hpp":"e5dd66225fc721943dd8706f930ba9dc04c9e9a535c9d2b70215e563eb23359c","tests/headers/const_ptr.hpp":"f55a4a914bf4cde1c9be63a99ea58acd3a4d6b722b9d6b4d570de91aa90a861d","tests/headers/const_resolved_ty.h":"572c999b6224bdb34fe807d75f27b49c9ca5d737150bbdbc18a4fdfa4c00ad1c","tests/headers/const_tparam.hpp":"32101adfd9b408ed29ebe330219cb66da199d194c54397cf0a6a51bf40d5770b","tests/headers/constant-evaluate.h":"f1f3dd8a07f7e45ad46ae1801406b989f3d731294149520675ddf4a7dd262766","tests/headers/constant-non-specialized-tp.hpp":"48cdc56a5689e1c7d8ba2bbc0f606b3f7a9b179d35b461d2afc3c41398b69c7e","tests/headers/constify-all-enums.h":"e6756535ff5ff68c122a0c40e621a61c968e6870128d9002d77a0f59d373aa3d","tests/headers/constify-enum.h":"f6fc217be7558f4cd25c6f7b7286f99e5124596364fcf0167133fcbf66377292","tests/headers/constructor-tp.hpp":"4d7e4e7f8642e2341679c84bc36eb609fd257b5475ad5ca216ffee974297e94f","tests/headers/constructors.hpp":"5ee56a7b05b71dc55bb9dfbf8816b5045142dc22f1c6d286319a6d4653a4984d","tests/headers/convert-floats.h":"b771a2ee9ed87b132494315b7a48449f783d903e96583a7642e61785b60d576e","tests/headers/crtp.hpp":"5ad7d00d2cbf243a89a8935eab5ab2997d7e828cbd54a5699a56064a37656152","tests/headers/dash_language.h":"acccf995806466b4f7ed7e4ef454ca1c8e849011a2bf52e5825a29ea52e01133","tests/headers/decl_extern_int_twice.h":"6ed5703307ac0712871a0e2e4cab19ebf26e3114e06b495274031376ae4027aa","tests/headers/decl_ptr_to_array.h":"76157bc1b4650bbec96ae52d672d42b71d0d0a16dbf9edc24b9e19d3e9d0ee52","tests/headers/disable-namespacing.hpp":"35e390e7aa60d675b2fa6a1737a48688fdcb05c7d2dc5506a5cd1d00a64bced6","tests/headers/duplicated-namespaces-definitions.hpp":"2940fc83895551c01969bb23432df847443fca306e26d9fb1bca8483887a3d23","tests/headers/duplicated-namespaces.hpp":"18b9fbbdbdea4952aaf0e308a95ba9453b92dc2b7e0c28e2175d8d9fc4db3c10","tests/headers/duplicated_constants_in_ns.hpp":"c3d2950b1e105c8c6ddd419999d20352ffd7d0ded0243cf14e1651dbf87adf42","tests/headers/elaborated.hpp":"d818eb9d298fc296fd35ef50e1b10658a66327748ba568c2b3e1e88e52651391","tests/headers/empty_template_param_name.hpp":"c9364c8a071bceecc0d6e4a764193a5cd653f688e9fbf543fff57b4263f0305c","tests/headers/enum.h":"513c9462f908150540fd4c31cf486c4e855b8b690786b02aa62ec86f969b637b","tests/headers/enum_alias.hpp":"684150ee62e3a1c9deb169c76bf32ac907751fc667d0a8ce8c2715371021c03f","tests/headers/enum_and_vtable_mangling.hpp":"dcfebe04ad23eb146f43ce3912aceb3170dff62552808cb7ce069946dc7868b4","tests/headers/enum_dupe.h":"d8c3ccd7155412ba5cc1cd37e0ae0005ca8460e570f5a8d8d7318615f19c264c","tests/headers/enum_explicit_type.hpp":"6295f549659449d977d451d6c07046af23309e8ac7d8be40c335f2fe79f897e1","tests/headers/enum_in_template_with_typedef.hpp":"6a1c37c7464b6ceb3916893698420cd339e55be17bf546381d5a4e020921c148","tests/headers/enum_negative.h":"9ddbe83fab84947ad2b8292a722ac7f5c3e1bfd1d1ad1ce08434ddee52f0e338","tests/headers/enum_packed.h":"1c8b49061675f9cf83c429eccc63725631883832d7e5ab30554accc6db7dc09b","tests/headers/eval-variadic-template-parameter.hpp":"d9190b6b7f96f678206c328161617d847e53b7356833c7ca32fc7ed4dddf6dee","tests/headers/extern.hpp":"68f1eba8b60316cd8bf52731a5dd29c84559342e7b66daffe6b769dc98f837ec","tests/headers/float128.hpp":"f0a676919df69373828a2a32f10b3b22a6c978c08864099603b10ddf444c26b7","tests/headers/forward-declaration-autoptr.hpp":"8c808baeac1af6c9e3efe0ee78d9ca76580502c713621e3f6ad2f298f0808bd8","tests/headers/forward-inherit-struct-with-fields.hpp":"3d63ec1d66bb080c4617fa945890cf70cf02f2af7b190e6a28fcf196fc8ea1f6","tests/headers/forward-inherit-struct.hpp":"c3869d51ecae6ff5ee6bd5d6f9710be60f93aea09e73d9b97a6c9068eb94e4de","tests/headers/forward_declared_complex_types.hpp":"deba01c271881fb324170c78ed26d37904cf6da0185b1d4472a9e3354be024ae","tests/headers/forward_declared_struct.h":"e31acf91e4d112e31bcba7040f2a1366853b442c52b9b04a40c73e0f2903bfe2","tests/headers/func_proto.h":"bf9519b408ee057b71bf72ad4ce910a5b75a15ae8daf12f536b65f9f9478c461","tests/headers/func_ptr.h":"9723273d527c1be57d6517cf8123e424225cd9d25a801f42618395ab5258d2fa","tests/headers/func_ptr_in_struct.h":"ce517145afed4eb8f9d14233248bc479a88a2fdcc52dc23029c498aa306f129c","tests/headers/func_with_array_arg.h":"1f6fff4283d90e96ba44dc7c64a778ad5e725fbf8167f04697bca20176eb6d2d","tests/headers/func_with_func_ptr_arg.h":"938475e53aafa207ebef7f4a84a9ec009d8dc4fa258fcab446318f5b0f1cc07b","tests/headers/in_class_typedef.hpp":"3bdc8ad6b9013b993dccec2d1bdec69801062fb41e251790bb5f93d89a562bd0","tests/headers/inherit-namespaced.hpp":"7636ac3a56620b20a8991b1a6d228fda174cbab02ddfb3117163700d8514fa55","tests/headers/inherit_named.hpp":"3fec93dcb2359d9acfb284acc39f7050362d8ecf05d828eb20eeb81d96f98f3c","tests/headers/inherit_typedef.hpp":"3ca1a4993c29282a18a0ba72186f3297ae26efa32cf22d05c1613fc799c9c466","tests/headers/inline-function.h":"028efdd98df34a85d9631357e95e7a6809ef6e8206ab3c00ad5181ca88826aed","tests/headers/inline_namespace.hpp":"ac8c6091fe3611877918ddfcf8a02934497ea4291c91ade237206f67fafd5cfe","tests/headers/inline_namespace_conservative.hpp":"820857eac505fc4bb3e5ba76d8cfc358d84b737ddbf99a2938522ee0fd59fba7","tests/headers/inline_namespace_whitelist.hpp":"6372a42e6c419d7e096b6fad3636d4076080951b6078120fa954869fa40c7b15","tests/headers/inner_const.hpp":"7325eb025bf4923ef4f8df164037d9398895b36107a1ed444bdcc5b419a56747","tests/headers/inner_template_self.hpp":"3a356ef1a1fefe9ec891bfdd9f2341b8094246caa2bf9fb321a6b061069f84ac","tests/headers/int128_t.h":"f460a6823e171a42be7bdcc6d7212b2821b01b8b887e3055fc6484a59f050789","tests/headers/issue-358.hpp":"4abe91b5721875d99c4102b174400b1ad365ea82f7367a6266c5e6dc21e26bbc","tests/headers/issue-372.hpp":"9ecf1029c04e3ec7462416a422172360c0a3ed5eb99a1536bafb5e3264ce23e9","tests/headers/issue-410.hpp":"dff6dbf8763017d35ab103ce15c19c9aa3ce61253dda7b8e313238b30214be68","tests/headers/issue-446.hpp":"3ddcc501769ce71548744c7de130df8088865bac33a8c7e4c0e4080db8c6227d","tests/headers/issue-447.hpp":"e96fe1ee3215196413903c0d2e63b53352c8d83077f661edf5dc5b257b2cb0fa","tests/headers/issue-493.hpp":"52f7dd68a1f93b71162b84edbde86ee60e37f500438b68e0dba31b43d4a5964c","tests/headers/issue_311.hpp":"b25e14cfa72cd5425f2cadfc0868d2bcacf6ac4c019945a840d19d7bb1811a67","tests/headers/issue_315.hpp":"6ebb5e7aeded8cf9b63f25478445432f8c76af731f7d587cff9932167fd32a75","tests/headers/jsval_layout_opaque.hpp":"5a82a83ee9e27d67641ad2805d616ea02a9828c4ab31aac9a08710f6b9f70b87","tests/headers/keywords.h":"9782ce81a46a25744ffbcf1970c0944f7230b9967085c3181ee3085ca7b2b2f0","tests/headers/layout.h":"cc1a48bfd90af7568e06c10726ba7686b553697cd26e3b5457e1e7171d4d826c","tests/headers/layout_align.h":"5008a958de96670dc72ea6922664487bfc0bdcd31b4bfdedcd005db2884f242b","tests/headers/layout_arp.h":"42decc3f72dd4b444a6b46cdb83ab9656a989a68bf7330c045b22a876dd00d87","tests/headers/layout_array.h":"d2f59d29d766cc22afd42a25e28cf9f307c42ee4d61504215a7e2c41bb0fc5b8","tests/headers/layout_cmdline_token.h":"3721c4a9104febc0d91141fae968ad059eb1df6a5811efe4234d4f3a9b8c6c3d","tests/headers/layout_eth_conf.h":"ade0ec6aa2a176ea4b9e112cbdfeeff57519f9e260a4287753e472659a5f31af","tests/headers/layout_kni_mbuf.h":"e18e7e16ac669207268529f5114e810ab748d4133ac073970dd306692ef36a44","tests/headers/layout_mbuf.h":"55084b56acfc91c3bbc8c70e7cf0883f41f2b9a956f2ca824f042191f323409b","tests/headers/macro-expr-basic.h":"bce59cdefb620457295199dd7b2839e1e397292d9bab10d54b5360b0574b17d6","tests/headers/macro-redef.h":"a5b95e2b26425119c567f45bfc3ad7d298c2efcad0132e9a9bfc3078dd0c4bcf","tests/headers/macro_const.h":"ec5c8d2009ad818c0fc242f76eaa8d3562633c50e50c0444fe293b3f8ed10ef0","tests/headers/maddness-is-avoidable.hpp":"8ba98872bf4292d014729e7b8248e750412a75cebdf2edbb684173aa0db7cf87","tests/headers/method-mangling.hpp":"b7ffe0e3b002bc032fab6b7785b03e635c0595bbc03d73fae4164611473dae2a","tests/headers/module-whitelisted.hpp":"a88e2a3e2f0f3edb205e60f9b08f4b1f7e017c15dc12e0541697006ba947025b","tests/headers/msvc-no-usr.hpp":"2b11fc139685e78a11bc224967360cb06f768b09e033a8be01d97002587383d9","tests/headers/multiple-inherit-empty-correct-layout.hpp":"7559184da00f812c7679bc5a863e5720447bd2b38a42310a2ec3114f405398a0","tests/headers/mutable.hpp":"cb85dc019dcf866ebf4e092d5c6ace509957c64c18eb48ccfb7b47116bc06c2c","tests/headers/namespace.hpp":"c0417b68013beb38ce781e385d0c7125b895d75e27a07ea6f05209050b9b5a19","tests/headers/nested.hpp":"0f56cd4d50004a75d8b54226f631db939ad918b7e68d48d4ebaaaab7dffc5eb4","tests/headers/nested_vtable.hpp":"c1a7f59161dda9429ccd146407a3899a27b1749c2feb4edf5537fe912f7f423d","tests/headers/nested_within_namespace.hpp":"841c9aae50dc4303e468878514939562870dabb94da909c82fa19bb2a35d1bfe","tests/headers/no-comments.h":"6dc35a97a702a99f43ac716dc6879137600b7f88961deaa7a148de505b3c2b4f","tests/headers/no-derive-debug.h":"7ffe15044735b63b36d0c1128f1c96f6fcc3a8e9e606e0aa020690cf5d8e0399","tests/headers/no-derive-default.h":"6b46fcd9ab3dd78309e748f231f92f3ff4d08f1b43e3960160e49548c0e6ff2f","tests/headers/no-recursive-whitelisting.h":"5153922c341e809cab973c5def7c503dc9c69d28275e0a30255fdbcc51c4210a","tests/headers/no-std.h":"3b7b5fabdf51588a48f11ff8a6961b652b4251125db45a32fd743a973ed929f4","tests/headers/no_copy.hpp":"b07c1dbc2f70aced75cee5421e78a1501cf6193508169c966394d86521b5c6bc","tests/headers/nsStyleAutoArray.hpp":"a80160e314377d8d5083165e9fd42e2e5ca31b211afca51b4b0e761f41e40824","tests/headers/objc_interface.h":"5a6ebe82a544b81e9dc75b9e11f03b8b5044758c0c2d0e43dfb0900602544f24","tests/headers/objc_interface_type.h":"b9831168069a724518c5a3c972271a8e82e9c74ea2f993ae9974a18c4a89ec5a","tests/headers/objc_method.h":"82a1b5786d5dc14f2d556c705e11fea4fe60f701e6a5de8f25baedae43a96542","tests/headers/only_bitfields.hpp":"bc9e1be2d946e5ac4116fa000c55fcbece500e98425404fc9d3b0cb9726ff7ba","tests/headers/opaque-tracing.hpp":"bf3326089c275be21b336cd4fb7ee5456d89c8444265daf49c3c5440b30f4264","tests/headers/opaque_in_struct.hpp":"31907f11d4b2d6fab2871b0d3314d2a3f5ebff5acae37f1071b5efd8090f8d58","tests/headers/opaque_pointer.hpp":"a7f97c2e2a6ef6433eba296b62d176568daa1383201631dbbcf081775b7a747e","tests/headers/opaque_typedef.hpp":"204404343f0050f8028678555ab6624777c678ce69ddbb9f54552011ea4e1a38","tests/headers/overflowed_enum.hpp":"0d927f0366546eb6459e5c81fcdd497ae8ba113ddc039af79847f0a05281a835","tests/headers/overloading.hpp":"2f0e0f44a6b1a7c4a72ab9e33863568ee7d24d2a271a701739aeac82c2d1ecc9","tests/headers/private.hpp":"2eae7fa2dd83fe3607e291746b3025b1e4265a0e1e584013fbea41fdfbd91725","tests/headers/public-dtor.hpp":"ed884a9c93569d1ad98c0af942dfc5f65e7cc67f579b2d1e6f940f25d4864f7c","tests/headers/redeclaration.hpp":"e9fc6785054ac6f6d4574f1846aefe933b09e26d398bd4cb47dad4ab8fb524ff","tests/headers/ref_argument_array.hpp":"c70b8b9ca935e2c9d0e78075f66220b33960fc4244c642d35cfcbe3c585e4371","tests/headers/reparented_replacement.hpp":"4f7a9cf64897155795abb0a55be2fde6512ff2108d7b3fd2495194efb2e1ca43","tests/headers/replace_template_alias.hpp":"982e0d2b7e6b9a7df1aa34d89df2520cc5d6b2b9c16f56c1369fe0ca3a88cb18","tests/headers/replace_use.hpp":"5bac44653be912b5af5062cfc4561e30cfcb7f91d321f8a6285656e2893cc349","tests/headers/replaces_double.hpp":"be76785b1742d8c2ae7011b230dd11e3c9d1b3b8218c2a76e4fe73c2870b5e80","tests/headers/resolved_type_def_function.h":"e080509e0cea0eb09262113b0f90d147928ffdd9a7cd9c3158628f5df5ecb426","tests/headers/same_struct_name_in_different_namespaces.hpp":"90a923bf707ef9de241cefba6397c088b6ffbad5ca7c997c4460af3876fedd04","tests/headers/size_t_template.hpp":"7e73bedf712c9f4b80f6e7f5e1411b91e01a3ea47bf2d261550ca785aae0c912","tests/headers/struct_containing_forward_declared_struct.h":"c66f635e39ee5b8fda94e9499b2fd682181ab819728ac268aa2ec40b62ac0e13","tests/headers/struct_typedef.h":"1ce4615befe234708d5beeb28efcaded42946849d16ef2b83af585ff8f86cb1d","tests/headers/struct_typedef_ns.hpp":"c912e88db616f57d9662d6223387ae996925dcec05edc48d87137cffc03b1094","tests/headers/struct_with_anon_struct.h":"4ce9c56a41b2fde0ae0062e5c87315dd69adc3ef79575b267256f47a9bd531b1","tests/headers/struct_with_anon_struct_array.h":"cb13830919d4039fd8a64b5aa972c05c21f5bd5d1f8722aa865bcd394f9f3c0c","tests/headers/struct_with_anon_struct_pointer.h":"4e0b669af481100125bd0bf1a4e17bd9ee1e03fb6cc8ee36875d71ecf6d63adb","tests/headers/struct_with_anon_union.h":"542567e8d54e51f43eb6699503d857fe5177ecd51b6ad5d5667a4992aa438f28","tests/headers/struct_with_anon_unnamed_struct.h":"0ae74d3b11fc64b30fed7f217f0cc51488c93b88a62755628699affdeeb8f5ef","tests/headers/struct_with_anon_unnamed_union.h":"71c9fa48a80fa5ee3714f76eb4faacae096f30ccaacbe51e8099760abf601aa9","tests/headers/struct_with_bitfields.h":"f8faa67dc47a88b0bd0b45d42ea170a714a67f0ef90b6f2e4870006bb499fd21","tests/headers/struct_with_derive_debug.h":"c4afb2aa9ae08b2e55270118f162cb611f011a64fa5b37e87aba7efd6a515a9b","tests/headers/struct_with_nesting.h":"695cdad138a59713aeee75050a8cf6f19bc1c16af7c49bb65e7a1fd6924e549a","tests/headers/struct_with_packing.h":"409c1b58233f45f65d4c6dc9bc233feea13549630b7267a320635fff0afce563","tests/headers/struct_with_struct.h":"f1d2c84e45396a4f5c16dbdd2db59d8bd4004d24e9287387bf55d532c7e4820e","tests/headers/struct_with_typedef_template_arg.hpp":"a620d87c5138d8b24842cddf906a00b2c74a95ee68d67d3b25a993264704f62d","tests/headers/template-fun-ty.hpp":"c0724925f55650d20f1feda29cb5f10758000a4ff5ea8629f45cd90442b5e651","tests/headers/template.hpp":"92517022906ea22b58f8edc58f4b2cf438e586c8b34b9b24f5a93f509fe6c45d","tests/headers/template_alias.hpp":"1df4a71f910aca9e6971927d48927baa777782e8a24c3880a68f97af41bb17d3","tests/headers/template_alias_basic.hpp":"676cb84ef33cd1ea7c0d4490304cb5f8d26f792035970aec6a81a1bed5fbdbc7","tests/headers/template_alias_namespace.hpp":"49e66046de03ffa6c00713cf184f80eb5182284b43bfa4457bc8657e2504ebc6","tests/headers/template_partial_specification.hpp":"d3a95aab8062961864e0709ba013ab8d631c21af88aff9f93df8c2217f4c61a2","tests/headers/template_typedef_transitive_param.hpp":"6c6ff83e79eb8c882f6fc8340ae3e21727205dbea882e9f7092ed1127775967d","tests/headers/template_typedefs.hpp":"12b5892aadbe8529e7fdecf2956f9e276824818ba6f3fbbde41cc5c7e628337a","tests/headers/templateref_opaque.hpp":"6ea0675c05821e4cd023e6541d8e33d6e762e1b30e55b1aa4f81360dcd93d324","tests/headers/type-referenced-by-whitelisted-function.h":"40ea5086de6ca2219c18db7b32846614737405eea8a3c3d70b198f1b1475d281","tests/headers/type_alias_empty.hpp":"f28175e7b5b843bbb35fe6214f0834ce9c8e6d0da52432cea252e2ed9a1c7d3c","tests/headers/type_alias_partial_template_especialization.hpp":"8c21d219cca03735d2a94bc0b9e9ecbee781d8c1655bd9caf7bedd51a6b77e95","tests/headers/type_alias_template_specialized.hpp":"15ceec92f8ccbacae71d7c8b59ecd8d81347cbcd0b4e0ed4366f17bdbbe95f1d","tests/headers/typedefd-array-as-function-arg.h":"7069fbb775a6b8af548ed0de2d24f3e2e35e10ebf8eed3c8841a220f58efa10b","tests/headers/typeref.hpp":"e314362ebff945a823b4a65bcd4931aaee3f93bc50baa57771da15fbf36c0b58","tests/headers/union-in-ns.hpp":"adb1d203918accd7177e55dd97ee64d1e908403c1e5c8c8f9ba4af5f50d6e522","tests/headers/union_dtor.hpp":"4ce6c54758690778348f84f8a876b8d0bb9cfecec95668147f815bb13d57d801","tests/headers/union_fields.hpp":"4f91a0013e39abbe0e10667f72ae902441ac2f1d9245c79ae182ae606794ceba","tests/headers/union_template.hpp":"142a263ee4db89573dade811057b0e5a4e0deae61c6859612068ebb5edd05503","tests/headers/union_with_anon_struct.h":"201c566f923d41e2b9cbc788f22d084e480d73ae1be9eed7096f1bac2870a034","tests/headers/union_with_anon_struct_bitfield.h":"2a7396f341ec34fa82f4705b3867d8546cbf8d2e62e790a70169bd807a70c8cb","tests/headers/union_with_anon_union.h":"5634be743d250fbfdacfc07a3bfc3b4d7659e8e201d0801e2d956aa0e1350a7e","tests/headers/union_with_anon_unnamed_struct.h":"5df9ec8170a3f712757a1000cc6f6883b95506dcaf8c94c59f03c7f26d3cc2df","tests/headers/union_with_anon_unnamed_union.h":"563f09841597a93f956a75db20261b8a9d290d88a385be343c6bc4cff6ecd66d","tests/headers/union_with_big_member.h":"d4622757fea8ff6ff7fb67de83e0e2511b078d3a74769bb847dfe1459317e5fe","tests/headers/union_with_nesting.h":"8e800c0fc5449d2317b51ec8a3e39e7680b7b0f29d00fe917e6c9d6da3854f0a","tests/headers/unknown_attr.h":"e03caf82b34e86a4a6ba71b5cc76581a92cf80173b3a1cbff7ec83758574bd31","tests/headers/use-core.h":"a518997b6c1dd33dbc092ec376b44d5b5e34270ee37ebcfe26a7229d24e3a75e","tests/headers/using.hpp":"5021a2a1ff4eaa6dabf5dd914a71357562d4a81573d2680342a3b193e9951496","tests/headers/var-tracing.hpp":"8b93ed99969a7a32ed1e49c52df77eee4ef077db758c0f58666c46efddff3adf","tests/headers/variadic-method.hpp":"9947eda68dfb6ddcd59b558f2fcdb2356bea27cfa9f22c6a46114ee937fb88b9","tests/headers/variadic_template_function.hpp":"232d2112a60f18e5704b64df573e814f91e45dd4d7be14d8b00a11ef436ee042","tests/headers/vector.hpp":"0a80c8886beaa6a9fc83e6652be26be1e6b23e1db006111a45b2c8a7f98e7dd1","tests/headers/virtual_dtor.hpp":"b1a3928a25c62d51d394e2192f91e250298c0357330241609103329f43185ae7","tests/headers/virtual_inheritance.hpp":"d92e8a26a939e9a7d575f3af0caf3081a30b3409f6f320432e13719cb7ddbad1","tests/headers/virtual_overloaded.hpp":"fea58d5f4a1814f7907e0066d1019e334ae0798454448eb825fb3f81dafd1a8d","tests/headers/vtable_recursive_sig.hpp":"5aae5edd330622207e6a803ad880b421d1530aa81fd57b8e10fe7faca186bd01","tests/headers/weird_bitfields.hpp":"86d0c0ddd64f812874889f21c395df49001bd91b114613c650806d46da0063b9","tests/headers/what_is_going_on.hpp":"8a7ccdcab365c12f176114a223da9aba83ecf6c98f349a56b74579bd0d9128ee","tests/headers/whitelist-namespaces-basic.hpp":"fae14a96e1d7fc9a32972d182869f0e64ff098ab7a9596bfdfd1ab14c7eb3950","tests/headers/whitelist-namespaces.hpp":"22c965df52d5641a16588eb8d718f523ba7fb16fed2f0a13847abcd78786af9a","tests/headers/whitelist_basic.hpp":"f63a40850cbf2cae91e804f89df184bfc352e222e6256c3c7055950d0c5d0fe9","tests/headers/whitelist_fix.hpp":"19f34cbdd375a43709fb73786814eccc5510ec902d5d645d7550dd4e70c5d9e0","tests/headers/whitelist_vars.h":"926f3437b49cb7434a0c9964a60182a4fd4ab29c25217621ee3510ab5e9ad282","tests/tests.rs":"868cd68740b6f4738595fa4e6578b49f1caced17cc278523a6ac724d8eee2af8","tests/uses/.gitignore":"377f40a9357416f0d0063605ea555bf4c876bf0adeec4e5093654c9427efe7d6"},"package":"facc480c409c373db3c870e377ce223e5e07d979efc2604691dc6f583e8ded0f"}
\ No newline at end of file
--- a/third_party/rust/bindgen/.travis.yml
+++ b/third_party/rust/bindgen/.travis.yml
@@ -10,17 +10,17 @@ addons:
 os:
   - linux
   - osx
 
 rust:
   - stable
 
 env:
-  - CARGO_TARGET_DIR=/tmp/bindgen LLVM_VERSION=3.8 BINDGEN_FEATURES=llvm_stable
+  - CARGO_TARGET_DIR=/tmp/bindgen LLVM_VERSION=3.8 BINDGEN_FEATURES=testing_only_llvm_stable
   - CARGO_TARGET_DIR=/tmp/bindgen LLVM_VERSION=3.9 BINDGEN_FEATURES=
 
 cache:
   directories:
     - $HOME/.cargo
 
 before_install: . ./ci/before_install.sh
 
--- a/third_party/rust/bindgen/CONTRIBUTING.md
+++ b/third_party/rust/bindgen/CONTRIBUTING.md
@@ -10,16 +10,17 @@ out to us in a GitHub issue, or stop by
 
 - [Code of Conduct](#code-of-conduct)
 - [Filing an Issue](#filing-an-issue)
 - [Building](#building)
 - [Testing](#testing)
   - [Overview](#overview)
   - [Running All Tests](#running-all-tests)
   - [Authoring New Tests](#authoring-new-tests)
+- [Generating Graphviz Dot File](#generating-graphviz-dot-file)
 - [Automatic code formatting](#automatic-code-formatting)
 - [Debug Logging](#debug-logging)
 - [Using `creduce` to Minimize Test Cases](#using-creduce-to-minimize-test-cases)
   - [Isolating Your Test Case](#isolating-your-test-case)
   - [Writing a Predicate Script](#writing-a-predicate-script)
 
 <!-- END doctoc generated TOC please keep comment here to allow auto update -->
 
@@ -64,17 +65,17 @@ the same path as above) to library searc
 $ export DYLD_LIBRARY_PATH=path/to/clang-3.9/lib # for macOS
 ```
 
 Additionally, you may want to build and test with the `docs_` feature to ensure
 that you aren't forgetting to document types and functions. CI will catch it if
 you forget, but the turn around will be a lot slower ;)
 
 ```
-$ cargo build --features "llvm_stable _docs"
+$ cargo build --features docs_
 ```
 
 ## Testing
 
 Code for binding generation and testing thereof is in the `bindgen` crate.
 The following sections assume you are working in that subdirectory.
 
 ### Overview
@@ -85,17 +86,17 @@ output Rust bindings live in `tests/expe
 For example, `tests/headers/my_header.h`'s expected generated Rust bindings
 would be `tests/expectations/tests/my_header.rs`.
 
 Run `cargo test` to compare generated Rust bindings to the expectations.
 
 ### Running All Tests
 
 ```
-$ cargo test [--features llvm_stable]
+$ cargo test [--all-features]
 ```
 
 ### Authoring New Tests
 
 To add a new test header to the suite, simply put it in the `tests/headers`
 directory. Next, run `bindgen` to generate the initial expected output Rust
 bindings. Put those in `tests/expectations/tests`.
 
@@ -107,16 +108,37 @@ specify them at the top of the test head
 ```
 
 Then verify the new Rust bindings compile and pass some basic tests:
 
 ```
 $ cargo test -p tests_expectations
 ```
 
+## Generating Graphviz Dot Files
+
+We have a special thing which will help you debug your codegen context if something
+will go wrong. It will generate a [`graphviz`](http://graphviz.org/pdf/dotguide.pdf)
+dot file and then you can create a PNG from it with `graphviz` tool in your OS.
+
+Here is an example how it could be done:
+
+```
+$ cargo run -- example.hpp --emit-ir-graphviz output.dot
+```
+
+It will generate your graphviz dot file and then you will need tog
+create a PNG from it with `graphviz`.
+
+Something like this:
+
+```
+$ dot -Tpng output.dot -o output.png
+```
+
 ## Automatic code formatting
 
 We use [`rustfmt`](https://github.com/rust-lang-nursery/rustfmt) to enforce a
 consistent code style across the whole `bindgen` code base. This is enforced in
 CI, and your pull requests will get automatically rejected if you don't
 re-format with the latest `rustfmt` before pushing.
 
 You can install the latest version of `rustfmt` with this command:
--- a/third_party/rust/bindgen/Cargo.toml
+++ b/third_party/rust/bindgen/Cargo.toml
@@ -8,17 +8,17 @@ authors = [
 description = "Automatically generates Rust FFI bindings to C and C++ libraries."
 keywords = ["bindings", "ffi", "code-generation"]
 categories = ["external-ffi-bindings", "development-tools::ffi"]
 license = "BSD-3-Clause"
 name = "bindgen"
 readme = "README.md"
 repository = "https://github.com/servo/rust-bindgen"
 documentation = "https://docs.rs/bindgen"
-version = "0.21.2"
+version = "0.22.0"
 build = "build.rs"
 
 exclude = ["tests/headers", "tests/expectations", "bindgen-integration", "ci"]
 
 [badges]
 travis-ci = { repository = "servo/rust-bindgen" }
 
 [lib]
@@ -34,17 +34,17 @@ clap = "2"
 shlex = "0.1"
 
 [build-dependencies]
 quasi_codegen = "0.29"
 
 [dependencies]
 cexpr = "0.2"
 cfg-if = "0.1.0"
-clang-sys = { version = "0.12", features = ["runtime", "clang_3_9"] }
+clang-sys = { version = "0.14", features = ["runtime", "clang_3_9"] }
 lazy_static = "0.2.1"
 rustc-serialize = "0.3.19"
 syntex_syntax = "0.54"
 regex = "0.2"
 # This kinda sucks: https://github.com/rust-lang/cargo/issues/1982
 clap = "2"
 
 [dependencies.aster]
@@ -61,13 +61,13 @@ version = "0.3"
 
 [dependencies.quasi]
 features = ["with-syntex"]
 version = "0.29"
 
 [features]
 assert_no_dangling_items = []
 default = ["logging"]
-llvm_stable = []
+testing_only_llvm_stable = []
 logging = ["env_logger", "log"]
 static = []
 # This feature only exists for CI -- don't use it!
 docs_ = []
--- a/third_party/rust/bindgen/README.md
+++ b/third_party/rust/bindgen/README.md
@@ -146,17 +146,17 @@ include!(concat!(env!("OUT_DIR"), "/exam
 ```
 
 ### Command Line Usage
 
 ```
 $ cargo install bindgen
 ```
 
-There are a few options documented when running `./bindgen --help`.
+There are a few options documented when running `bindgen --help`. Bindgen is installed to `~/.cargo/bin`. You have to add that directory to your path to use `bindgen`.
 
 ### C++
 
 `bindgen` can handle most C++ features, but not all of them (C++ is hard!)
 
 Notable C++ features that are unsupported or only partially supported:
 
 * Partial template specialization
--- a/third_party/rust/bindgen/build.rs
+++ b/third_party/rust/bindgen/build.rs
@@ -6,16 +6,17 @@ mod codegen {
     pub fn main() {
         let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
         let src = Path::new("src/codegen/mod.rs");
         let dst = Path::new(&out_dir).join("codegen.rs");
 
         quasi_codegen::expand(&src, &dst).unwrap();
         println!("cargo:rerun-if-changed=src/codegen/mod.rs");
         println!("cargo:rerun-if-changed=src/codegen/helpers.rs");
+        println!("cargo:rerun-if-changed=src/codegen/struct_layout.rs");
     }
 }
 
 mod testgen {
     use std::char;
     use std::env;
     use std::ffi::OsStr;
     use std::fs::{self, File};
--- a/third_party/rust/bindgen/src/chooser.rs
+++ b/third_party/rust/bindgen/src/chooser.rs
@@ -1,17 +1,18 @@
 //! A public API for more fine-grained customization of bindgen behavior.
 
 pub use ir::enum_ty::{EnumVariantCustomBehavior, EnumVariantValue};
 pub use ir::int::IntKind;
 use std::fmt;
+use std::panic::UnwindSafe;
 
 /// A trait to allow configuring different kinds of types in different
 /// situations.
-pub trait TypeChooser: fmt::Debug {
+pub trait TypeChooser: fmt::Debug + UnwindSafe {
     /// The integer kind an integer macro should have, given a name and the
     /// value of that macro, or `None` if you want the default to be chosen.
     fn int_macro(&self, _name: &str, _value: i64) -> Option<IntKind> {
         None
     }
 
     /// This function should return whether, given the a given enum variant
     /// name, and value, returns whether this enum variant will forcibly be a
--- a/third_party/rust/bindgen/src/clang.rs
+++ b/third_party/rust/bindgen/src/clang.rs
@@ -64,17 +64,21 @@ impl Cursor {
     /// This is not necessarily a valid identifier. It includes extra
     /// information, such as parameters for a function, etc.
     pub fn display_name(&self) -> String {
         unsafe { cxstring_into_string(clang_getCursorDisplayName(self.x)) }
     }
 
     /// Get the mangled name of this cursor's referent.
     pub fn mangling(&self) -> String {
-        unsafe { cxstring_into_string(clang_Cursor_getMangling(self.x)) }
+        if clang_Cursor_getMangling::is_loaded() {
+            unsafe { cxstring_into_string(clang_Cursor_getMangling(self.x)) }
+        } else {
+            self.spelling()
+        }
     }
 
     /// Get the `Cursor` for this cursor's referent's lexical parent.
     ///
     /// The lexical parent is the parent of the definition. The semantic parent
     /// is the parent of the declaration. Generally, the lexical parent doesn't
     /// have any effect on semantics, while the semantic parent does.
     ///
@@ -127,21 +131,21 @@ impl Cursor {
     ///
     /// NOTE: This may not return `Some` for some non-fully specialized
     /// templates, see #193 and #194.
     pub fn num_template_args(&self) -> Option<u32> {
         // XXX: `clang_Type_getNumTemplateArguments` is sort of reliable, while
         // `clang_Cursor_getNumTemplateArguments` is totally unreliable.
         // Therefore, try former first, and only fallback to the latter if we
         // have to.
-        self.cur_type().num_template_args()
+        self.cur_type()
+            .num_template_args()
             .or_else(|| {
-                let n: c_int = unsafe {
-                    clang_Cursor_getNumTemplateArguments(self.x)
-                };
+                let n: c_int =
+                    unsafe { clang_Cursor_getNumTemplateArguments(self.x) };
 
                 if n >= 0 {
                     Some(n as u32)
                 } else {
                     debug_assert_eq!(n, -1);
                     None
                 }
             })
@@ -207,30 +211,26 @@ impl Cursor {
         unsafe { clang_getCursorKind(self.x) }
     }
 
     /// Returns true is the cursor is a definition
     pub fn is_definition(&self) -> bool {
         unsafe { clang_isCursorDefinition(self.x) != 0 }
     }
 
-    /// Is the referent an anonymous record definition?
-    pub fn is_anonymous(&self) -> bool {
-        unsafe { clang_Cursor_isAnonymous(self.x) != 0 }
-    }
-
     /// Is the referent a template specialization?
     pub fn is_template_specialization(&self) -> bool {
         self.specialized().is_some()
     }
 
     /// Is the referent a fully specialized template specialization without any
     /// remaining free template arguments?
     pub fn is_fully_specialized_template(&self) -> bool {
         self.is_template_specialization() &&
+        self.kind() != CXCursor_ClassTemplatePartialSpecialization &&
         self.num_template_args().unwrap_or(0) > 0
     }
 
     /// Is the referent a template specialization that still has remaining free
     /// template arguments?
     pub fn is_in_non_fully_specialized_template(&self) -> bool {
         if self.is_toplevel() {
             return false;
@@ -356,16 +356,51 @@ impl Cursor {
     {
         unsafe {
             clang_visitChildren(self.x,
                                 visit_children::<Visitor>,
                                 mem::transmute(&mut visitor));
         }
     }
 
+    /// Collect all of this cursor's children into a vec and return them.
+    pub fn collect_children(&self) -> Vec<Cursor> {
+        let mut children = vec![];
+        self.visit(|c| {
+            children.push(c);
+            CXChildVisit_Continue
+        });
+        children
+    }
+
+    /// Does this cursor have any children?
+    pub fn has_children(&self) -> bool {
+        let mut has_children = false;
+        self.visit(|_| {
+            has_children = true;
+            CXChildVisit_Break
+        });
+        has_children
+    }
+
+    /// Does this cursor have at least `n` children?
+    pub fn has_at_least_num_children(&self, n: usize) -> bool {
+        assert!(n > 0);
+        let mut num_left = n;
+        self.visit(|_| {
+            num_left -= 1;
+            if num_left == 0 {
+                CXChildVisit_Break
+            } else {
+                CXChildVisit_Continue
+            }
+        });
+        num_left == 0
+    }
+
     /// Returns whether the given location contains a cursor with the given
     /// kind in the first level of nesting underneath (doesn't look
     /// recursively).
     pub fn contains_cursor(&self, kind: CXCursorKind) -> bool {
         let mut found = false;
 
         self.visit(|c| if c.kind() == kind {
             found = true;
@@ -443,17 +478,21 @@ impl Cursor {
     ///
     /// This only applies to functions and variables.
     pub fn linkage(&self) -> CXLinkageKind {
         unsafe { clang_getCursorLinkage(self.x) }
     }
 
     /// Get the visibility of this cursor's referent.
     pub fn visibility(&self) -> CXVisibilityKind {
-        unsafe { clang_getCursorVisibility(self.x) }
+        if clang_getCursorVisibility::is_loaded() {
+            unsafe { clang_getCursorVisibility(self.x) }
+        } else {
+            CXVisibility_Default
+        }
     }
 
     /// Given that this cursor's referent is a function, return cursors to its
     /// parameters.
     pub fn args(&self) -> Option<Vec<Cursor>> {
         // XXX: We might want to use and keep num_args
         // match self.kind() {
         // CXCursor_FunctionDecl |
@@ -491,19 +530,35 @@ impl Cursor {
     /// Get the access specifier for this cursor's referent.
     pub fn access_specifier(&self) -> CX_CXXAccessSpecifier {
         unsafe { clang_getCXXAccessSpecifier(self.x) }
     }
 
     /// Is this cursor's referent a field declaration that is marked as
     /// `mutable`?
     pub fn is_mutable_field(&self) -> bool {
+        clang_CXXField_isMutable::is_loaded() &&
         unsafe { clang_CXXField_isMutable(self.x) != 0 }
     }
 
+    /// Get the offset of the field represented by the Cursor.
+    pub fn offset_of_field(&self) -> Result<usize, LayoutError> {
+        if !clang_Cursor_getOffsetOfField::is_loaded() {
+            return Err(LayoutError::from(-1));
+        }
+
+        let offset = unsafe { clang_Cursor_getOffsetOfField(self.x) };
+
+        if offset < 0 {
+            Err(LayoutError::from(offset as i32))
+        } else {
+            Ok(offset as usize)
+        }
+    }
+
     /// Is this cursor's referent a member function that is declared `static`?
     pub fn method_is_static(&self) -> bool {
         unsafe { clang_CXXMethod_isStatic(self.x) != 0 }
     }
 
     /// Is this cursor's referent a member function that is declared `const`?
     pub fn method_is_const(&self) -> bool {
         unsafe { clang_CXXMethod_isConst(self.x) != 0 }
@@ -518,16 +573,24 @@ impl Cursor {
     pub fn is_virtual_base(&self) -> bool {
         unsafe { clang_isVirtualBase(self.x) != 0 }
     }
 
     /// Try to evaluate this cursor.
     pub fn evaluate(&self) -> Option<EvalResult> {
         EvalResult::new(*self)
     }
+
+    /// Return the result type for this cursor
+    pub fn ret_type(&self) -> Option<Type> {
+        let rt = Type {
+            x: unsafe { clang_getCursorResultType(self.x) },
+        };
+        if rt.is_valid() { Some(rt) } else { None }
+    }
 }
 
 extern "C" fn visit_children<Visitor>(cur: CXCursor,
                                       _parent: CXCursor,
                                       data: CXClientData)
                                       -> CXChildVisitResult
     where Visitor: FnMut(Cursor) -> CXChildVisitResult,
 {
@@ -549,17 +612,17 @@ impl Eq for Cursor {}
 
 impl Hash for Cursor {
     fn hash<H: Hasher>(&self, state: &mut H) {
         unsafe { clang_hashCursor(self.x) }.hash(state)
     }
 }
 
 /// The type of a node in clang's AST.
-#[derive(Clone)]
+#[derive(Clone, Copy)]
 pub struct Type {
     x: CXType,
 }
 
 impl PartialEq for Type {
     fn eq(&self, other: &Self) -> bool {
         unsafe { clang_equalTypes(self.x, other.x) != 0 }
     }
@@ -594,20 +657,16 @@ pub enum LayoutError {
     InvalidFieldName,
     /// An unknown layout error.
     Unknown,
 }
 
 impl ::std::convert::From<i32> for LayoutError {
     fn from(val: i32) -> Self {
         use self::LayoutError::*;
-        let val = match CXTypeLayoutError::from_raw(val) {
-            Some(val) => val,
-            None => return Unknown,
-        };
 
         match val {
             CXTypeLayoutError_Invalid => Invalid,
             CXTypeLayoutError_Incomplete => Incomplete,
             CXTypeLayoutError_Dependent => Dependent,
             CXTypeLayoutError_NotConstantSize => NotConstantSize,
             CXTypeLayoutError_InvalidFieldName => InvalidFieldName,
             _ => Unknown,
@@ -625,16 +684,41 @@ impl Type {
     pub fn declaration(&self) -> Cursor {
         unsafe {
             Cursor {
                 x: clang_getTypeDeclaration(self.x),
             }
         }
     }
 
+    /// Get the canonical declaration of this type, if it is available.
+    pub fn canonical_declaration(&self,
+                                 location: Option<&Cursor>)
+                                 -> Option<CanonicalTypeDeclaration> {
+        let mut declaration = self.declaration();
+        if !declaration.is_valid() {
+            if let Some(location) = location {
+                let mut location = *location;
+                if let Some(referenced) = location.referenced() {
+                    location = referenced;
+                }
+                if location.is_template_like() {
+                    declaration = location;
+                }
+            }
+        }
+
+        let canonical = declaration.canonical();
+        if canonical.is_valid() && canonical.kind() != CXCursor_NoDeclFound {
+            Some(CanonicalTypeDeclaration(*self, canonical))
+        } else {
+            None
+        }
+    }
+
     /// Get a raw display name for this type.
     pub fn spelling(&self) -> String {
         unsafe { cxstring_into_string(clang_getTypeSpelling(self.x)) }
     }
 
     /// Is this type const qualified?
     pub fn is_const(&self) -> bool {
         unsafe { clang_isConstQualifiedType(self.x) != 0 }
@@ -699,20 +783,22 @@ impl Type {
             debug_assert_eq!(n, -1);
             None
         }
     }
 
     /// If this type is a class template specialization, return its
     /// template arguments. Otherwise, return None.
     pub fn template_args(&self) -> Option<TypeTemplateArgIterator> {
-        self.num_template_args().map(|n| TypeTemplateArgIterator {
-            x: self.x,
-            length: n,
-            index: 0,
+        self.num_template_args().map(|n| {
+            TypeTemplateArgIterator {
+                x: self.x,
+                length: n,
+                index: 0,
+            }
         })
     }
 
     /// Given that this type is a pointer type, return the type that it points
     /// to.
     pub fn pointee_type(&self) -> Option<Type> {
         match self.kind() {
             CXType_Pointer |
@@ -804,27 +890,46 @@ impl Type {
         self.is_valid() && self.kind() != CXType_Unexposed
     }
 
     /// Is this type a fully specialized template?
     pub fn is_fully_specialized_template(&self) -> bool {
         // Yep, the spelling of this containing type-parameter is extremely
         // nasty... But can happen in <type_traits>. Unfortunately I couldn't
         // reduce it enough :(
-        self.template_args().map_or(false, |args| {
-            args.len() > 0
-        }) && match self.declaration().kind() {
+        self.template_args().map_or(false, |args| args.len() > 0) &&
+        match self.declaration().kind() {
             CXCursor_ClassTemplatePartialSpecialization |
             CXCursor_TypeAliasTemplateDecl |
             CXCursor_TemplateTemplateParameter => false,
             _ => true,
         }
     }
 }
 
+/// The `CanonicalTypeDeclaration` type exists as proof-by-construction that its
+/// cursor is the canonical declaration for its type. If you have a
+/// `CanonicalTypeDeclaration` instance, you know for sure that the type and
+/// cursor match up in a canonical declaration relationship, and it simply
+/// cannot be otherwise.
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub struct CanonicalTypeDeclaration(Type, Cursor);
+
+impl CanonicalTypeDeclaration {
+    /// Get the type.
+    pub fn ty(&self) -> &Type {
+        &self.0
+    }
+
+    /// Get the type's canonical declaration cursor.
+    pub fn cursor(&self) -> &Cursor {
+        &self.1
+    }
+}
+
 /// An iterator for a type's template arguments.
 pub struct TypeTemplateArgIterator {
     x: CXType,
     length: u32,
     index: u32,
 }
 
 impl Iterator for TypeTemplateArgIterator {
@@ -1315,18 +1420,16 @@ pub fn ast_dump(c: &Cursor, depth: isize
                      format!(" {}is-definition? {}",
                              prefix,
                              c.is_definition()));
         print_indent(depth,
                      format!(" {}is-declaration? {}",
                              prefix,
                              c.is_declaration()));
         print_indent(depth,
-                     format!(" {}is-anonymous? {}", prefix, c.is_anonymous()));
-        print_indent(depth,
                      format!(" {}is-inlined-function? {}",
                              prefix,
                              c.is_inlined_function()));
 
         let templ_kind = c.template_kind();
         if templ_kind != CXCursor_NoDeclFound {
             print_indent(depth,
                          format!(" {}template-kind = {}",
@@ -1358,43 +1461,46 @@ pub fn ast_dump(c: &Cursor, depth: isize
             print_indent(depth, format!(" {}enum-val = {}", prefix, val));
         }
         if let Some(ty) = c.typedef_type() {
             print_indent(depth,
                          format!(" {}typedef-type = {}",
                                  prefix,
                                  type_to_str(ty.kind())));
         }
+        if let Some(ty) = c.ret_type() {
+            print_indent(depth,
+                         format!(" {}ret-type = {}",
+                                 prefix,
+                                 type_to_str(ty.kind())));
+        }
 
         if let Some(refd) = c.referenced() {
             if refd != *c {
                 println!("");
                 print_cursor(depth,
                              String::from(prefix) + "referenced.",
                              &refd);
-                print_cursor(depth, String::from(prefix) + "referenced.", &refd);
             }
         }
 
         let canonical = c.canonical();
         if canonical != *c {
             println!("");
             print_cursor(depth,
                          String::from(prefix) + "canonical.",
                          &canonical);
-            print_cursor(depth, String::from(prefix) + "canonical.", &canonical);
         }
 
         if let Some(specialized) = c.specialized() {
             if specialized != *c {
                 println!("");
                 print_cursor(depth,
                              String::from(prefix) + "specialized.",
                              &specialized);
-                print_cursor(depth, String::from(prefix) + "specialized.", &specialized);
             }
         }
     }
 
     fn print_type<S: AsRef<str>>(depth: isize, prefix: S, ty: &Type) {
         let prefix = prefix.as_ref();
 
         let kind = ty.kind();
--- a/third_party/rust/bindgen/src/codegen/mod.rs
+++ b/third_party/rust/bindgen/src/codegen/mod.rs
@@ -1,31 +1,35 @@
 mod helpers;
+mod struct_layout;
 
 use self::helpers::{BlobTyBuilder, attributes};
+use self::struct_layout::{align_to, bytes_from_bits};
+use self::struct_layout::{bytes_from_bits_pow2, StructLayoutTracker};
 use aster;
 
 use ir::annotations::FieldAccessorKind;
 use ir::comp::{Base, CompInfo, CompKind, Field, Method, MethodKind};
 use ir::context::{BindgenContext, ItemId};
-use ir::derive::{CanDeriveCopy, CanDeriveDebug};
+use ir::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault};
 use ir::enum_ty::{Enum, EnumVariant, EnumVariantValue};
 use ir::function::{Function, FunctionSig};
 use ir::int::IntKind;
-use ir::item::{Item, ItemAncestors, ItemCanonicalName, ItemCanonicalPath};
+use ir::item::{Item, ItemAncestors, ItemCanonicalName, ItemCanonicalPath,
+               ItemSet};
 use ir::item_kind::ItemKind;
 use ir::layout::Layout;
 use ir::module::Module;
 use ir::objc::ObjCInterface;
 use ir::ty::{Type, TypeKind};
-use ir::type_collector::ItemSet;
 use ir::var::Var;
 
 use std::borrow::Cow;
 use std::cell::Cell;
+use std::cmp;
 use std::collections::{HashSet, VecDeque};
 use std::collections::hash_map::{Entry, HashMap};
 use std::fmt::Write;
 use std::mem;
 use std::ops;
 use syntax::abi::Abi;
 use syntax::ast;
 use syntax::codemap::{Span, respan};
@@ -355,18 +359,17 @@ impl CodeGenerator for Module {
                 if whitelisted_items.contains(child) {
                     *found_any = true;
                     ctx.resolve_item(*child)
                         .codegen(ctx, result, whitelisted_items, &());
                 }
             }
 
             if item.id() == ctx.root_module() {
-                let saw_union = result.saw_union;
-                if saw_union && !ctx.options().unstable_rust {
+                if result.saw_union && !ctx.options().unstable_rust {
                     utils::prepend_union_types(ctx, &mut *result);
                 }
                 if result.saw_incomplete_array {
                     utils::prepend_incomplete_array_types(ctx, &mut *result);
                 }
                 if ctx.need_bindegen_complex_type() {
                     utils::prepend_complex_type(ctx, &mut *result);
                 }
@@ -513,17 +516,17 @@ impl CodeGenerator for Type {
             TypeKind::NullPtr |
             TypeKind::Int(..) |
             TypeKind::Float(..) |
             TypeKind::Complex(..) |
             TypeKind::Array(..) |
             TypeKind::Pointer(..) |
             TypeKind::BlockPointer |
             TypeKind::Reference(..) |
-            TypeKind::TemplateRef(..) |
+            TypeKind::TemplateInstantiation(..) |
             TypeKind::Function(..) |
             TypeKind::ResolvedTypeRef(..) |
             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::Comp(ref ci) => {
@@ -680,20 +683,26 @@ impl<'a> CodeGenerator for Vtable<'a> {
     fn codegen<'b>(&self,
                    ctx: &BindgenContext,
                    result: &mut CodegenResult<'b>,
                    _whitelisted_items: &ItemSet,
                    item: &Item) {
         assert_eq!(item.id(), self.item_id);
         // For now, generate an empty struct, later we should generate function
         // pointers and whatnot.
+        let mut attributes = vec![attributes::repr("C")];
+
+        if ctx.options().derive_default {
+            attributes.push(attributes::derives(&["Default"]))
+        }
+
         let vtable = aster::AstBuilder::new()
             .item()
             .pub_()
-            .with_attr(attributes::repr("C"))
+            .with_attrs(attributes)
             .struct_(self.canonical_name(ctx))
             .build();
         result.push(vtable);
     }
 }
 
 impl<'a> ItemCanonicalName for Vtable<'a> {
     fn canonical_name(&self, ctx: &BindgenContext) -> String {
@@ -703,113 +712,121 @@ impl<'a> ItemCanonicalName for Vtable<'a
 
 impl<'a> ItemToRustTy for Vtable<'a> {
     fn to_rust_ty(&self, ctx: &BindgenContext) -> P<ast::Ty> {
         aster::ty::TyBuilder::new().id(self.canonical_name(ctx))
     }
 }
 
 struct Bitfield<'a> {
-    index: usize,
+    index: &'a mut usize,
     fields: Vec<&'a Field>,
 }
 
 impl<'a> Bitfield<'a> {
-    fn new(index: usize, fields: Vec<&'a Field>) -> Self {
+    fn new(index: &'a mut usize, fields: Vec<&'a Field>) -> Self {
         Bitfield {
             index: index,
             fields: fields,
         }
     }
 
     fn codegen_fields(self,
                       ctx: &BindgenContext,
                       fields: &mut Vec<ast::StructField>,
-                      methods: &mut Vec<ast::ImplItem>) {
+                      _methods: &mut Vec<ast::ImplItem>)
+                      -> Layout {
         use aster::struct_field::StructFieldBuilder;
-        use std::cmp;
-        let mut total_width = self.fields
-            .iter()
-            .fold(0u32, |acc, f| acc + f.bitfield().unwrap());
-
-        if !total_width.is_power_of_two() || total_width < 8 {
-            total_width = cmp::max(8, total_width.next_power_of_two());
-        }
-        debug_assert_eq!(total_width % 8, 0);
-        let total_width_in_bytes = total_width as usize / 8;
-
-        let bitfield_type =
-            BlobTyBuilder::new(Layout::new(total_width_in_bytes,
-                                           total_width_in_bytes))
-                .build();
-        let field_name = format!("_bitfield_{}", self.index);
-        let field_ident = ctx.ext_cx().ident_of(&field_name);
-        let field = StructFieldBuilder::named(&field_name)
-            .pub_()
-            .build_ty(bitfield_type.clone());
-        fields.push(field);
-
-
-        let mut offset = 0;
+
+        // NOTE: What follows is reverse-engineered from LLVM's
+        // lib/AST/RecordLayoutBuilder.cpp
+        //
+        // FIXME(emilio): There are some differences between Microsoft and the
+        // Itanium ABI, but we'll ignore those and stick to Itanium for now.
+        //
+        // Also, we need to handle packed bitfields and stuff.
+        // TODO(emilio): Take into account C++'s wide bitfields, and
+        // packing, sigh.
+        let mut total_size_in_bits = 0;
+        let mut max_align = 0;
+        let mut unfilled_bits_in_last_unit = 0;
+        let mut field_size_in_bits = 0;
+        *self.index += 1;
+        let mut last_field_name = format!("_bitfield_{}", self.index);
+        let mut last_field_align = 0;
+
         for field in self.fields {
             let width = field.bitfield().unwrap();
-            let field_name = field.name()
-                .map(ToOwned::to_owned)
-                .unwrap_or_else(|| format!("at_offset_{}", offset));
-
             let field_item = ctx.resolve_item(field.ty());
             let field_ty_layout = field_item.kind()
                 .expect_type()
                 .layout(ctx)
                 .expect("Bitfield without layout? Gah!");
 
-            let field_type = field_item.to_rust_ty(ctx);
-            let int_type = BlobTyBuilder::new(field_ty_layout).build();
-
-            let getter_name = ctx.rust_ident(&field_name);
-            let setter_name = ctx.ext_cx()
-                .ident_of(&format!("set_{}", &field_name));
-            let mask = ((1usize << width) - 1) << offset;
-            let prefix = ctx.trait_prefix();
-            // The transmute is unfortunate, but it's needed for enums in
-            // bitfields.
-            let item = quote_item!(ctx.ext_cx(),
-                impl X {
-                    #[inline]
-                    pub fn $getter_name(&self) -> $field_type {
-                        unsafe {
-                            ::$prefix::mem::transmute(
-                                (
-                                    (self.$field_ident &
-                                        ($mask as $bitfield_type))
-                                     >> $offset
-                                ) as $int_type
-                            )
-                        }
-                    }
-
-                    #[inline]
-                    pub fn $setter_name(&mut self, val: $field_type) {
-                        self.$field_ident &= !($mask as $bitfield_type);
-                        self.$field_ident |=
-                            (val as $int_type as $bitfield_type << $offset) &
-                                ($mask as $bitfield_type);
-                    }
-                }
-            )
-                .unwrap();
-
-            let items = match item.unwrap().node {
-                ast::ItemKind::Impl(_, _, _, _, _, items) => items,
-                _ => unreachable!(),
-            };
-
-            methods.extend(items.into_iter());
-            offset += width;
+            let field_align = field_ty_layout.align;
+
+            if field_size_in_bits != 0 &&
+                (width == 0 || width as usize > unfilled_bits_in_last_unit) {
+                field_size_in_bits = align_to(field_size_in_bits, field_align);
+                // Push the new field.
+                let ty =
+                    BlobTyBuilder::new(Layout::new(bytes_from_bits_pow2(field_size_in_bits),
+                                                   bytes_from_bits_pow2(last_field_align)))
+                        .build();
+
+                let field = StructFieldBuilder::named(&last_field_name)
+                    .pub_()
+                    .build_ty(ty);
+                fields.push(field);
+
+                // TODO(emilio): dedup this.
+                *self.index += 1;
+                last_field_name = format!("_bitfield_{}", self.index);
+
+                // Now reset the size and the rest of stuff.
+                // unfilled_bits_in_last_unit = 0;
+                field_size_in_bits = 0;
+                last_field_align = 0;
+            }
+
+            // TODO(emilio): Create the accessors. Problem here is that we still
+            // don't know which one is going to be the final alignment of the
+            // bitfield, and whether we have to index in it. Thus, we don't know
+            // which integer type do we need.
+            //
+            // We could push them to a Vec or something, but given how buggy
+            // they where maybe it's not a great idea?
+            field_size_in_bits += width as usize;
+            total_size_in_bits += width as usize;
+
+
+            let data_size = align_to(field_size_in_bits, field_align * 8);
+
+            max_align = cmp::max(max_align, field_align);
+
+            // NB: The width here is completely, absolutely intentional.
+            last_field_align = cmp::max(last_field_align, width as usize);
+
+            unfilled_bits_in_last_unit = data_size - field_size_in_bits;
         }
+
+        if field_size_in_bits != 0 {
+            // Push the last field.
+            let ty =
+                BlobTyBuilder::new(Layout::new(bytes_from_bits_pow2(field_size_in_bits),
+                                               bytes_from_bits_pow2(last_field_align)))
+                    .build();
+
+            let field = StructFieldBuilder::named(&last_field_name)
+                .pub_()
+                .build_ty(ty);
+            fields.push(field);
+        }
+
+        Layout::new(bytes_from_bits(total_size_in_bits), max_align)
     }
 }
 
 impl CodeGenerator for CompInfo {
     type Extra = Item;
 
     fn codegen<'a>(&self,
                    ctx: &BindgenContext,
@@ -857,27 +874,30 @@ impl CodeGenerator for CompInfo {
                                 ::$prefix::mem::size_of::<$ident>());
                 let align_of_expr = quote_expr!(ctx.ext_cx(),
                                 ::$prefix::mem::align_of::<$ident>());
                 let size = layout.size;
                 let align = layout.align;
                 let item = quote_item!(ctx.ext_cx(),
                                        #[test]
                                        fn $fn_name() {
-                                           assert_eq!($size_of_expr, $size);
-                                           assert_eq!($align_of_expr, $align);
+                                           assert_eq!($size_of_expr, $size,
+                                                      concat!("Size of template specialization: ", stringify!($ident)));
+                                           assert_eq!($align_of_expr, $align,
+                                                      concat!("Alignment of template specialization: ", stringify!($ident)));
                                        })
                     .unwrap();
                 result.push(item);
             }
             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 self.packed() {
             attributes.push(attributes::repr_list(&["C", "packed"]));
         } else {
@@ -885,16 +905,22 @@ impl CodeGenerator for CompInfo {
         }
 
         let is_union = self.kind() == CompKind::Union;
         let mut derives = vec![];
         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;
+        }
+
         if item.can_derive_copy(ctx, ()) &&
            !item.annotations().disallow_copy() {
             derives.push("Copy");
             if !applicable_template_args.is_empty() {
                 // FIXME: This requires extra logic if you have a big array in a
                 // templated struct. The reason for this is that the magic:
                 //     fn clone(&self) -> Self { *self }
                 // doesn't work for templates.
@@ -935,27 +961,30 @@ 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);
         if self.needs_explicit_vtable(ctx) {
             let vtable =
                 Vtable::new(item.id(), self.methods(), self.base_members());
             vtable.codegen(ctx, result, whitelisted_items, item);
 
             let vtable_type = vtable.to_rust_ty(ctx).to_ptr(true, ctx.span());
 
             let vtable_field = StructFieldBuilder::named("vtable_")
                 .pub_()
                 .build_ty(vtable_type);
 
+            struct_layout.saw_vtable();
+
             fields.push(vtable_field);
         }
 
         for (i, base) in self.base_members().iter().enumerate() {
             // Virtual bases are already taken into account by the vtable
             // pointer.
             //
             // FIXME(emilio): Is this always right?
@@ -980,16 +1009,18 @@ impl CodeGenerator for CompInfo {
 
             let inner = base.ty.to_rust_ty(ctx);
             let field_name = if i == 0 {
                 "_base".into()
             } else {
                 format!("_base_{}", i)
             };
 
+            struct_layout.saw_base(base_ty);
+
             let field = StructFieldBuilder::named(field_name)
                 .pub_()
                 .build_ty(inner);
             fields.push(field);
         }
         if is_union {
             result.saw_union();
         }
@@ -1033,19 +1064,21 @@ impl CodeGenerator for CompInfo {
                 }
             }
 
             // Flush the current bitfield.
             if current_bitfield_width.is_some() {
                 debug_assert!(!current_bitfield_fields.is_empty());
                 let bitfield_fields =
                     mem::replace(&mut current_bitfield_fields, vec![]);
-                bitfield_count += 1;
-                Bitfield::new(bitfield_count, bitfield_fields)
+                let bitfield_layout = Bitfield::new(&mut bitfield_count,
+                                                    bitfield_fields)
                     .codegen_fields(ctx, &mut fields, &mut methods);
+                struct_layout.saw_bitfield_batch(bitfield_layout);
+
                 current_bitfield_width = None;
                 current_bitfield_layout = None;
             }
             debug_assert!(current_bitfield_fields.is_empty());
 
             if let Some(width) = field.bitfield() {
                 let layout = field_ty.layout(ctx)
                     .expect("Bitfield type without layout?");
@@ -1066,18 +1099,17 @@ impl CodeGenerator for CompInfo {
 
             // NB: In unstable rust we use proper `union` types.
             let ty = if is_union && !ctx.options().unstable_rust {
                 if ctx.options().enable_cxx_namespaces {
                     quote_ty!(ctx.ext_cx(), root::__BindgenUnionField<$ty>)
                 } else {
                     quote_ty!(ctx.ext_cx(), __BindgenUnionField<$ty>)
                 }
-            } else if let Some(item) =
-                field_ty.is_incomplete_array(ctx) {
+            } else if let Some(item) = field_ty.is_incomplete_array(ctx) {
                 result.saw_incomplete_array();
 
                 let inner = item.to_rust_ty(ctx);
 
                 if ctx.options().enable_cxx_namespaces {
                     quote_ty!(ctx.ext_cx(), root::__IncompleteArrayField<$inner>)
                 } else {
                     quote_ty!(ctx.ext_cx(), __IncompleteArrayField<$inner>)
@@ -1095,16 +1127,21 @@ impl CodeGenerator for CompInfo {
             let field_name = match field.name() {
                 Some(name) => ctx.rust_mangle(name).into_owned(),
                 None => {
                     anonymous_field_count += 1;
                     format!("__bindgen_anon_{}", anonymous_field_count)
                 }
             };
 
+            if let Some(padding_field) =
+                struct_layout.pad_field(&field_name, field_ty, field.offset()) {
+                fields.push(padding_field);
+            }
+
             let is_private = field.annotations()
                 .private_fields()
                 .unwrap_or(fields_should_be_private);
 
             let accessor_kind = field.annotations()
                 .accessor_kind()
                 .unwrap_or(struct_accessor_kind);
 
@@ -1186,28 +1223,32 @@ impl CodeGenerator for CompInfo {
         // Flush the last bitfield if any.
         //
         // FIXME: Reduce duplication with the loop above.
         // FIXME: May need to pass current_bitfield_layout too.
         if current_bitfield_width.is_some() {
             debug_assert!(!current_bitfield_fields.is_empty());
             let bitfield_fields = mem::replace(&mut current_bitfield_fields,
                                                vec![]);
-            bitfield_count += 1;
-            Bitfield::new(bitfield_count, bitfield_fields)
+            let bitfield_layout = Bitfield::new(&mut bitfield_count,
+                                                bitfield_fields)
                 .codegen_fields(ctx, &mut fields, &mut methods);
+            struct_layout.saw_bitfield_batch(bitfield_layout);
         }
         debug_assert!(current_bitfield_fields.is_empty());
 
         if is_union && !ctx.options().unstable_rust {
             let layout = layout.expect("Unable to get layout information?");
             let ty = BlobTyBuilder::new(layout).build();
             let field = StructFieldBuilder::named("bindgen_union_field")
                 .pub_()
                 .build_ty(ty);
+
+            struct_layout.saw_union(layout);
+
             fields.push(field);
         }
 
         // Yeah, sorry about that.
         if item.is_opaque(ctx) {
             fields.clear();
             methods.clear();
             for i in 0..template_args_used.len() {
@@ -1222,16 +1263,26 @@ impl CodeGenerator for CompInfo {
                             .pub_()
                             .build_ty(ty);
                     fields.push(field);
                 }
                 None => {
                     warn!("Opaque type without layout! Expect dragons!");
                 }
             }
+        } else if !is_union && !self.is_unsized(ctx) {
+            if let Some(padding_field) =
+                layout.and_then(|layout| struct_layout.pad_struct(&canonical_name, layout)) {
+                fields.push(padding_field);
+            }
+
+            if let Some(align_field) =
+                layout.and_then(|layout| struct_layout.align_struct(layout)) {
+                fields.push(align_field);
+            }
         }
 
         // C requires every struct to be addressable, so what C compilers do is
         // making the struct 1-byte sized.
         //
         // NOTE: This check is conveniently here to avoid the dummy fields we
         // may add for unused template parameters.
         if self.is_unsized(ctx) {
@@ -1291,38 +1342,89 @@ impl CodeGenerator for CompInfo {
         // 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 applicable_template_args.is_empty() && !self.found_unknown_attr() {
+        if applicable_template_args.is_empty() {
             for var in self.inner_vars() {
                 ctx.resolve_item(*var)
                     .codegen(ctx, result, whitelisted_items, &());
             }
 
             if let Some(layout) = layout {
                 let fn_name = format!("bindgen_test_layout_{}", canonical_name);
                 let fn_name = ctx.rust_ident_raw(&fn_name);
-                let ident = ctx.rust_ident_raw(&canonical_name);
+                let type_name = ctx.rust_ident_raw(&canonical_name);
                 let prefix = ctx.trait_prefix();
                 let size_of_expr = quote_expr!(ctx.ext_cx(),
-                                ::$prefix::mem::size_of::<$ident>());
+                                ::$prefix::mem::size_of::<$type_name>());
                 let align_of_expr = quote_expr!(ctx.ext_cx(),
-                                ::$prefix::mem::align_of::<$ident>());
+                                ::$prefix::mem::align_of::<$type_name>());
                 let size = layout.size;
                 let align = layout.align;
+
+                let check_struct_align = if align > mem::size_of::<*mut ()>() {
+                    // FIXME when [RFC 1358](https://github.com/rust-lang/rust/issues/33626) ready
+                    None
+                } 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
+                let too_many_base_vtables = self.base_members()
+                    .iter()
+                    .filter(|base| {
+                        ctx.resolve_type(base.ty).has_vtable(ctx)
+                    })
+                    .count() > 1;
+
+                let should_skip_field_offset_checks = item.is_opaque(ctx) ||
+                                                      too_many_base_vtables;
+
+                let check_field_offset = if should_skip_field_offset_checks {
+                    None
+                } else {
+                    let asserts = self.fields()
+                    .iter()
+                    .filter(|field| field.bitfield().is_none())
+                    .flat_map(|field| {
+                        field.name().and_then(|name| {
+                            field.offset().and_then(|offset| {
+                                let field_offset = offset / 8;
+                                let field_name = ctx.rust_ident(name);
+
+                                quote_item!(ctx.ext_cx(),
+                                    assert_eq!(unsafe { &(*(0 as *const $type_name)).$field_name as *const _ as usize },
+                                               $field_offset,
+                                               concat!("Alignment of field: ", stringify!($type_name), "::", stringify!($field_name)));
+                                )
+                            })
+                        })
+                    }).collect::<Vec<P<ast::Item>>>();
+
+                    Some(asserts)
+                };
+
                 let item = quote_item!(ctx.ext_cx(),
                     #[test]
                     fn $fn_name() {
-                        assert_eq!($size_of_expr, $size);
-                        assert_eq!($align_of_expr, $align);
+                        assert_eq!($size_of_expr,
+                                   $size,
+                                   concat!("Size of: ", stringify!($type_name)));
+
+                        $check_struct_align
+                        $check_field_offset
                     })
                     .unwrap();
                 result.push(item);
             }
 
             let mut method_names = Default::default();
             if ctx.options().codegen_config.methods {
                 for method in self.methods() {
@@ -1349,18 +1451,24 @@ impl CodeGenerator for CompInfo {
                                         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().ty().path().id(&canonical_name).build();
+        let ty_for_impl = aster::AstBuilder::new()
+            .ty()
+            .path()
+            .segment(&canonical_name)
+            .with_generics(generics.clone())
+            .build()
+            .build();
+
         if needs_clone_impl {
             let impl_ = quote_item!(ctx.ext_cx(),
                 impl X {
                     fn clone(&self) -> Self { *self }
                 }
             );
 
             let impl_ = match impl_.unwrap().node {
@@ -1376,16 +1484,42 @@ impl CodeGenerator for CompInfo {
                 .build()
                 .with_generics(generics.clone())
                 .with_items(impl_)
                 .build_ty(ty_for_impl.clone());
 
             result.push(clone_impl);
         }
 
+        if needs_default_impl {
+            let prefix = ctx.trait_prefix();
+            let impl_ = quote_item!(ctx.ext_cx(),
+                impl X {
+                    fn default() -> Self { unsafe { ::$prefix::mem::zeroed() } }
+                }
+            );
+
+            let impl_ = match impl_.unwrap().node {
+                ast::ItemKind::Impl(_, _, _, _, _, ref items) => items.clone(),
+                _ => unreachable!(),
+            };
+
+            let default_impl = aster::AstBuilder::new()
+                .item()
+                .impl_()
+                .trait_()
+                .id("Default")
+                .build()
+                .with_generics(generics.clone())
+                .with_items(impl_)
+                .build_ty(ty_for_impl.clone());
+
+            result.push(default_impl);
+        }
+
         if !methods.is_empty() {
             let methods = aster::AstBuilder::new()
                 .item()
                 .impl_()
                 .with_generics(generics)
                 .with_items(methods)
                 .build_ty(ty_for_impl);
             result.push(methods);
@@ -1508,19 +1642,20 @@ impl MethodCodegen for Method {
         let mut exprs = helpers::ast_ty::arguments_from_signature(&signature,
                                                                   ctx);
 
         let mut stmts = vec![];
 
         // If it's a constructor, we need to insert an extra parameter with a
         // variable called `__bindgen_tmp` we're going to create.
         if self.is_constructor() {
+            let prefix = ctx.trait_prefix();
             let tmp_variable_decl =
                 quote_stmt!(ctx.ext_cx(),
-                            let mut __bindgen_tmp = ::std::mem::uninitialized())
+                            let mut __bindgen_tmp = ::$prefix::mem::uninitialized())
                 .unwrap();
             stmts.push(tmp_variable_decl);
             exprs[0] = quote_expr!(ctx.ext_cx(), &mut __bindgen_tmp);
         } else if !self.is_static() {
             assert!(!exprs.is_empty());
             exprs[0] = if self.is_const() {
                 quote_expr!(ctx.ext_cx(), &*self)
             } else {
@@ -2036,33 +2171,33 @@ impl ToRustTy for Type {
                 }
             }
             TypeKind::Function(ref fs) => {
                 let ty = fs.to_rust_ty(ctx, item);
                 let prefix = ctx.trait_prefix();
                 quote_ty!(ctx.ext_cx(), ::$prefix::option::Option<$ty>)
             }
             TypeKind::Array(item, len) => {
-                let inner = item.to_rust_ty(ctx);
-                aster::ty::TyBuilder::new().array(len).build(inner)
+                let ty = item.to_rust_ty(ctx);
+                aster::ty::TyBuilder::new().array(len).build(ty)
             }
             TypeKind::Enum(..) => {
                 let path = item.namespace_aware_canonical_path(ctx);
                 aster::AstBuilder::new().ty().path().ids(path).build()
             }
-            TypeKind::TemplateRef(inner, ref template_args) => {
+            TypeKind::TemplateInstantiation(inner, ref template_args) => {
                 // PS: Sorry for the duplication here.
                 let mut inner_ty = inner.to_rust_ty(ctx).unwrap();
 
                 if let ast::TyKind::Path(_, ref mut path) = inner_ty.node {
                     let template_args = template_args.iter()
                         .map(|arg| arg.to_rust_ty(ctx))
                         .collect::<Vec<_>>();
 
-                    path.segments.last_mut().unwrap().parameters = if 
+                    path.segments.last_mut().unwrap().parameters = if
                         template_args.is_empty() {
                         None
                     } else {
                         Some(P(ast::PathParameters::AngleBracketed(
                             ast::AngleBracketedParameterData {
                                 lifetimes: vec![],
                                 types: P::from_vec(template_args),
                                 bindings: P::from_vec(vec![]),
@@ -2148,81 +2283,28 @@ impl ToRustTy for Type {
     }
 }
 
 impl ToRustTy for FunctionSig {
     type Extra = Item;
 
     fn to_rust_ty(&self, ctx: &BindgenContext, _item: &Item) -> P<ast::Ty> {
         // TODO: we might want to consider ignoring the reference return value.
-        let return_item = ctx.resolve_item(self.return_type());
-        let ret =
-            if let TypeKind::Void = *return_item.kind().expect_type().kind() {
-                ast::FunctionRetTy::Default(ctx.span())
-            } else {
-                ast::FunctionRetTy::Ty(return_item.to_rust_ty(ctx))
-            };
-
-        let mut unnamed_arguments = 0;
-        let arguments = self.argument_types().iter().map(|&(ref name, ty)| {
-            let arg_item = ctx.resolve_item(ty);
-            let arg_ty = arg_item.kind().expect_type();
-
-            // From the C90 standard[1]:
-            //
-            //     A declaration of a parameter as "array of type" shall be
-            //     adjusted to "qualified pointer to type", where the type
-            //     qualifiers (if any) are those specified within the [ and ] of
-            //     the array type derivation.
-            //
-            // [1]: http://c0x.coding-guidelines.com/6.7.5.3.html
-            let arg_ty = match *arg_ty.canonical_type(ctx).kind() {
-                TypeKind::Array(t, _) => {
-                    t.to_rust_ty(ctx).to_ptr(arg_ty.is_const(), ctx.span())
-                },
-                TypeKind::Pointer(inner) => {
-                    let inner = ctx.resolve_item(inner);
-                    let inner_ty = inner.expect_type();
-                    if let TypeKind::ObjCInterface(_) = *inner_ty.canonical_type(ctx).kind() {
-                        quote_ty!(ctx.ext_cx(), id)
-                    } else {
-                        arg_item.to_rust_ty(ctx)
-                    }
-                },
-                _ => {
-                    arg_item.to_rust_ty(ctx)
-                }
-            };
-
-            let arg_name = match *name {
-                Some(ref name) => ctx.rust_mangle(name).into_owned(),
-                None => {
-                    unnamed_arguments += 1;
-                    format!("arg{}", unnamed_arguments)
-                }
-            };
-
-            assert!(!arg_name.is_empty());
-
-            ast::Arg {
-                ty: arg_ty,
-                pat: aster::AstBuilder::new().pat().id(arg_name),
-                id: ast::DUMMY_NODE_ID,
-            }
-        }).collect::<Vec<_>>();
+        let ret = utils::fnsig_return_ty(ctx, &self);
+        let arguments = utils::fnsig_arguments(ctx, &self);
 
         let decl = P(ast::FnDecl {
             inputs: arguments,
             output: ret,
             variadic: self.is_variadic(),
         });
 
         let fnty = ast::TyKind::BareFn(P(ast::BareFnTy {
             unsafety: ast::Unsafety::Unsafe,
-            abi: self.abi(),
+            abi: self.abi().expect("Invalid abi for function!"),
             lifetimes: vec![],
             decl: decl,
         }));
 
         P(ast::Ty {
             id: ast::DUMMY_NODE_ID,
             node: fnty,
             span: ctx.span(),
@@ -2292,17 +2374,18 @@ impl CodeGenerator for Function {
             ident: ctx.rust_ident_raw(&canonical_name),
             attrs: attributes,
             node: foreign_item_kind,
             id: ast::DUMMY_NODE_ID,
             span: ctx.span(),
             vis: ast::Visibility::Public,
         };
 
-        let item = ForeignModBuilder::new(signature.abi())
+        let item = ForeignModBuilder::new(signature.abi()
+                .expect("Invalid abi for function!"))
             .with_foreign_item(foreign_item)
             .build(ctx);
 
         result.push(item);
     }
 }
 
 impl CodeGenerator for ObjCInterface {
@@ -2311,34 +2394,52 @@ impl CodeGenerator for ObjCInterface {
                    ctx: &BindgenContext,
                    result: &mut CodegenResult<'a>,
                    _whitelisted_items: &ItemSet,
                    _: &Item) {
         let mut impl_items = vec![];
         let mut trait_items = vec![];
 
         for method in self.methods() {
-            let method_name = ctx.rust_ident(method.name());
-
-            let body = quote_stmt!(ctx.ext_cx(), msg_send![self, $method_name])
+            let signature = method.signature();
+            let fn_args = utils::fnsig_arguments(ctx, signature);
+            let fn_ret = utils::fnsig_return_ty(ctx, signature);
+            let sig = aster::AstBuilder::new()
+                .method_sig()
+                .unsafe_()
+                .fn_decl()
+                .self_()
+                .build(ast::SelfKind::Value(ast::Mutability::Immutable))
+                .with_args(fn_args.clone())
+                .build(fn_ret);
+
+            // Collect the actual used argument names
+            let arg_names: Vec<_> = fn_args.iter()
+                .map(|ref arg| match arg.pat.node {
+                    ast::PatKind::Ident(_, ref spanning, _) => {
+                        spanning.node.name.as_str().to_string()
+                    }
+                    _ => {
+                        panic!("odd argument!");
+                    }
+                })
+                .collect();
+
+            let methods_and_args =
+                ctx.rust_ident(&method.format_method_call(&arg_names));
+            let body = quote_stmt!(ctx.ext_cx(),
+                                   msg_send![self, $methods_and_args])
                 .unwrap();
             let block = ast::Block {
                 stmts: vec![body],
                 id: ast::DUMMY_NODE_ID,
                 rules: ast::BlockCheckMode::Default,
                 span: ctx.span(),
             };
 
-            let sig = aster::AstBuilder::new()
-                .method_sig()
-                .unsafe_()
-                .fn_decl()
-                .self_()
-                .build(ast::SelfKind::Value(ast::Mutability::Immutable))
-                .build(ast::FunctionRetTy::Default(ctx.span()));
             let attrs = vec![];
 
             let impl_item = ast::ImplItem {
                 id: ast::DUMMY_NODE_ID,
                 ident: ctx.rust_ident(method.rust_name()),
                 vis: ast::Visibility::Inherited, // Public,
                 attrs: attrs.clone(),
                 node: ast::ImplItemKind::Method(sig.clone(), P(block)),
@@ -2395,34 +2496,41 @@ pub fn codegen(context: &mut BindgenCont
 
         if context.options().emit_ir {
             for &id in whitelisted_items.iter() {
                 let item = context.resolve_item(id);
                 println!("ir: {:?} = {:#?}", id, item);
             }
         }
 
+        if let Some(path) = context.options().emit_ir_graphviz.as_ref() {
+            match context.emit_ir_graphviz(path.clone()) {
+                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, &());
 
         result.items
     })
 }
 
 mod utils {
     use super::ItemToRustTy;
     use aster;
     use ir::context::{BindgenContext, ItemId};
+    use ir::function::FunctionSig;
     use ir::item::{Item, ItemCanonicalPath};
     use ir::ty::TypeKind;
     use std::mem;
     use syntax::ast;
     use syntax::ptr::P;
 
-
     pub fn prepend_objc_header(ctx: &BindgenContext,
                                result: &mut Vec<P<ast::Item>>) {
         let use_objc = if ctx.options().objc_extern_crate {
             quote_item!(ctx.ext_cx(),
                 use objc;
             )
                 .unwrap()
         } else {
@@ -2499,19 +2607,19 @@ mod utils {
             .unwrap();
 
         let union_field_copy_impl = quote_item!(&ctx.ext_cx(),
             impl<T> ::$prefix::marker::Copy for __BindgenUnionField<T> {}
         )
             .unwrap();
 
         let union_field_debug_impl = quote_item!(ctx.ext_cx(),
-            impl<T> ::std::fmt::Debug for __BindgenUnionField<T> {
-                fn fmt(&self, fmt: &mut ::std::fmt::Formatter)
-                       -> ::std::fmt::Result {
+            impl<T> ::$prefix::fmt::Debug for __BindgenUnionField<T> {
+                fn fmt(&self, fmt: &mut ::$prefix::fmt::Formatter)
+                       -> ::$prefix::fmt::Result {
                     fmt.write_str("__BindgenUnionField")
                 }
             }
         )
             .unwrap();
 
         let items = vec![union_field_decl,
                          union_field_impl,
@@ -2525,16 +2633,17 @@ mod utils {
     }
 
     pub fn prepend_incomplete_array_types(ctx: &BindgenContext,
                                           result: &mut Vec<P<ast::Item>>) {
         let prefix = ctx.trait_prefix();
 
         let incomplete_array_decl = quote_item!(ctx.ext_cx(),
             #[repr(C)]
+            #[derive(Default)]
             pub struct __IncompleteArrayField<T>(
                 ::$prefix::marker::PhantomData<T>);
         )
             .unwrap();
 
         let incomplete_array_impl = quote_item!(&ctx.ext_cx(),
             impl<T> __IncompleteArrayField<T> {
                 #[inline]
@@ -2692,9 +2801,73 @@ mod utils {
         };
 
         let decl_ty = signature.to_rust_ty(ctx, sig);
         match decl_ty.unwrap().node {
             ast::TyKind::BareFn(bare_fn) => bare_fn.unwrap().decl,
             _ => panic!("How did this happen exactly?"),
         }
     }
+
+    pub fn fnsig_return_ty(ctx: &BindgenContext,
+                           sig: &FunctionSig)
+                           -> ast::FunctionRetTy {
+        let return_item = ctx.resolve_item(sig.return_type());
+        if let TypeKind::Void = *return_item.kind().expect_type().kind() {
+            ast::FunctionRetTy::Default(ctx.span())
+        } else {
+            ast::FunctionRetTy::Ty(return_item.to_rust_ty(ctx))
+        }
+    }
+
+    pub fn fnsig_arguments(ctx: &BindgenContext,
+                           sig: &FunctionSig)
+                           -> Vec<ast::Arg> {
+        use super::ToPtr;
+        let mut unnamed_arguments = 0;
+        sig.argument_types().iter().map(|&(ref name, ty)| {
+            let arg_item = ctx.resolve_item(ty);
+            let arg_ty = arg_item.kind().expect_type();
+
+            // From the C90 standard[1]:
+            //
+            //     A declaration of a parameter as "array of type" shall be
+            //     adjusted to "qualified pointer to type", where the type
+            //     qualifiers (if any) are those specified within the [ and ] of
+            //     the array type derivation.
+            //
+            // [1]: http://c0x.coding-guidelines.com/6.7.5.3.html
+            let arg_ty = match *arg_ty.canonical_type(ctx).kind() {
+                TypeKind::Array(t, _) => {
+                    t.to_rust_ty(ctx).to_ptr(ctx.resolve_type(t).is_const(), ctx.span())
+                },
+                TypeKind::Pointer(inner) => {
+                    let inner = ctx.resolve_item(inner);
+                    let inner_ty = inner.expect_type();
+                    if let TypeKind::ObjCInterface(_) = *inner_ty.canonical_type(ctx).kind() {
+                        quote_ty!(ctx.ext_cx(), id)
+                    } else {
+                        arg_item.to_rust_ty(ctx)
+                    }
+                },
+                _ => {
+                    arg_item.to_rust_ty(ctx)
+                }
+            };
+
+            let arg_name = match *name {
+                Some(ref name) => ctx.rust_mangle(name).into_owned(),
+                None => {
+                    unnamed_arguments += 1;
+                    format!("arg{}", unnamed_arguments)
+                }
+            };
+
+            assert!(!arg_name.is_empty());
+
+            ast::Arg {
+                ty: arg_ty,
+                pat: aster::AstBuilder::new().pat().id(arg_name),
+                id: ast::DUMMY_NODE_ID,
+            }
+        }).collect::<Vec<_>>()
+    }
 }
new file mode 100644
--- /dev/null
+++ b/third_party/rust/bindgen/src/codegen/struct_layout.rs
@@ -0,0 +1,334 @@
+//! Helpers for code generation that need struct layout
+
+use super::helpers::BlobTyBuilder;
+
+use aster::struct_field::StructFieldBuilder;
+
+use ir::comp::CompInfo;
+use ir::context::BindgenContext;
+use ir::layout::Layout;
+use ir::ty::{Type, TypeKind};
+use std::cmp;
+use std::mem;
+
+use syntax::ast;
+
+/// Trace the layout of struct.
+pub struct StructLayoutTracker<'a, 'ctx: 'a> {
+    ctx: &'a BindgenContext<'ctx>,
+    comp: &'a CompInfo,
+    latest_offset: usize,
+    padding_count: usize,
+    latest_field_layout: Option<Layout>,
+    max_field_align: usize,
+    last_field_was_bitfield: bool,
+}
+
+/// Returns a size aligned to a given value.
+pub fn align_to(size: usize, align: usize) -> usize {
+    if align == 0 {
+        return size;
+    }
+
+    let rem = size % align;
+    if rem == 0 {
+        return size;
+    }
+
+    size + align - rem
+}
+
+/// Returns the amount of bytes from a given amount of bytes, rounding up.
+pub fn bytes_from_bits(n: usize) -> usize {
+    if n % 8 == 0 {
+        return n / 8;
+    }
+
+    n / 8 + 1
+}
+
+/// Returns the lower power of two byte count that can hold at most n bits.
+pub fn bytes_from_bits_pow2(mut n: usize) -> usize {
+    if n == 0 {
+        return 0;
+    }
+
+    if n <= 8 {
+        return 1;
+    }
+
+    if !n.is_power_of_two() {
+        n = n.next_power_of_two();
+    }
+
+    n / 8
+}
+
+#[test]
+fn test_align_to() {
+    assert_eq!(align_to(1, 1), 1);
+    assert_eq!(align_to(1, 2), 2);
+    assert_eq!(align_to(1, 4), 4);
+    assert_eq!(align_to(5, 1), 5);
+    assert_eq!(align_to(17, 4), 20);
+}
+
+#[test]
+fn test_bytes_from_bits_pow2() {
+    assert_eq!(bytes_from_bits_pow2(0), 0);
+    for i in 1..9 {
+        assert_eq!(bytes_from_bits_pow2(i), 1);
+    }
+    for i in 9..17 {
+        assert_eq!(bytes_from_bits_pow2(i), 2);
+    }
+    for i in 17..33 {
+        assert_eq!(bytes_from_bits_pow2(i), 4);
+    }
+}
+
+#[test]
+fn test_bytes_from_bits() {
+    assert_eq!(bytes_from_bits(0), 0);
+    for i in 1..9 {
+        assert_eq!(bytes_from_bits(i), 1);
+    }
+    for i in 9..17 {
+        assert_eq!(bytes_from_bits(i), 2);
+    }
+    for i in 17..25 {
+        assert_eq!(bytes_from_bits(i), 3);
+    }
+}
+
+impl<'a, 'ctx> StructLayoutTracker<'a, 'ctx> {
+    pub fn new(ctx: &'a BindgenContext<'ctx>, comp: &'a CompInfo) -> Self {
+        StructLayoutTracker {
+            ctx: ctx,
+            comp: comp,
+            latest_offset: 0,
+            padding_count: 0,
+            latest_field_layout: None,
+            max_field_align: 0,
+            last_field_was_bitfield: false,
+        }
+    }
+
+    pub fn saw_vtable(&mut self) {
+        let ptr_size = mem::size_of::<*mut ()>();
+        self.latest_offset += ptr_size;
+        self.latest_field_layout = Some(Layout::new(ptr_size, ptr_size));
+        self.max_field_align = ptr_size;
+    }
+
+    pub fn saw_base(&mut self, base_ty: &Type) {
+        if let Some(layout) = base_ty.layout(self.ctx) {
+            self.align_to_latest_field(layout);
+
+            self.latest_offset += self.padding_bytes(layout) + layout.size;
+            self.latest_field_layout = Some(layout);
+            self.max_field_align = cmp::max(self.max_field_align, layout.align);
+        }
+    }
+
+    pub fn saw_bitfield_batch(&mut self, layout: Layout) {
+        self.align_to_latest_field(layout);
+
+        self.latest_offset += layout.size;
+
+        debug!("Offset: <bitfield>: {} -> {}",
+               self.latest_offset - layout.size,
+               self.latest_offset);
+
+        self.latest_field_layout = Some(layout);
+        self.last_field_was_bitfield = true;
+        // NB: We intentionally don't update the max_field_align here, since our
+        // bitfields code doesn't necessarily guarantee it, so we need to
+        // actually generate the dummy alignment.
+    }
+
+    pub fn saw_union(&mut self, layout: Layout) {
+        self.align_to_latest_field(layout);
+
+        self.latest_offset += self.padding_bytes(layout) + layout.size;
+        self.latest_field_layout = Some(layout);
+        self.max_field_align = cmp::max(self.max_field_align, layout.align);
+    }
+
+    /// Add a padding field if necessary for a given new field _before_ adding
+    /// that field.
+    pub fn pad_field(&mut self,
+                     field_name: &str,
+                     field_ty: &Type,
+                     field_offset: Option<usize>)
+                     -> Option<ast::StructField> {
+        let mut field_layout = match field_ty.layout(self.ctx) {
+            Some(l) => l,
+            None => return None,
+        };
+
+        if let TypeKind::Array(inner, len) = *field_ty.canonical_type(self.ctx).kind() {
+            // FIXME(emilio): As an _ultra_ hack, we correct the layout returned
+            // by arrays of structs that have a bigger alignment than what we
+            // can support.
+            //
+            // This means that the structs in the array are super-unsafe to
+            // access, since they won't be properly aligned, but *shrug*.
+            if let Some(layout) = self.ctx.resolve_type(inner).layout(self.ctx) {
+                if layout.align > mem::size_of::<*mut ()>() {
+                    field_layout.size =
+                        align_to(layout.size, layout.align) * len;
+                    field_layout.align = mem::size_of::<*mut ()>();
+                }
+            }
+        }
+
+        let will_merge_with_bitfield = self.align_to_latest_field(field_layout);
+
+        let padding_layout = if self.comp.packed() {
+            None
+        } else {
+            let padding_bytes = match field_offset {
+                Some(offset) if offset / 8 > self.latest_offset => {
+                    offset / 8 - self.latest_offset
+                }
+                _ if will_merge_with_bitfield || field_layout.align == 0 => 0,
+                _ => self.padding_bytes(field_layout),
+            };
+
+            // Otherwise the padding is useless.
+            let need_padding = padding_bytes >= field_layout.align;
+
+            self.latest_offset += padding_bytes;
+
+            debug!("Offset: <padding>: {} -> {}",
+                   self.latest_offset - padding_bytes,
+                   self.latest_offset);
+
+            debug!("align field {} to {}/{} with {} padding bytes {:?}",
+                field_name,
+                self.latest_offset,
+                field_offset.unwrap_or(0) / 8,
+                padding_bytes,
+                field_layout);
+
+            if need_padding && padding_bytes != 0 {
+                Some(Layout::new(padding_bytes, field_layout.align))
+            } else {
+                None
+            }
+        };
+
+        self.latest_offset += field_layout.size;
+        self.latest_field_layout = Some(field_layout);
+        self.max_field_align = cmp::max(self.max_field_align, field_layout.align);
+        self.last_field_was_bitfield = false;
+
+        debug!("Offset: {}: {} -> {}",
+               field_name,
+               self.latest_offset - field_layout.size,
+               self.latest_offset);
+
+        padding_layout.map(|layout| self.padding_field(layout))
+    }
+
+    pub fn pad_struct(&mut self, name: &str, layout: Layout) -> Option<ast::StructField> {
+        if layout.size < self.latest_offset {
+            error!("Calculated wrong layout for {}, too more {} bytes",
+                   name, self.latest_offset - layout.size);
+            return None
+        }
+
+        let padding_bytes = layout.size - self.latest_offset;
+
+        // We always pad to get to the correct size if the struct is one of
+        // those we can't align properly.
+        //
+        // Note that if the last field we saw was a bitfield, we may need to pad
+        // regardless, because bitfields don't respect alignment as strictly as
+        // other fields.
+        if padding_bytes > 0 &&
+            (padding_bytes >= layout.align ||
+             (self.last_field_was_bitfield &&
+                padding_bytes >= self.latest_field_layout.unwrap().align) ||
+             layout.align > mem::size_of::<*mut ()>()) {
+            let layout = if self.comp.packed() {
+                Layout::new(padding_bytes, 1)
+            } else if self.last_field_was_bitfield ||
+                      layout.align > mem::size_of::<*mut ()>() {
+                // We've already given up on alignment here.
+                Layout::for_size(padding_bytes)
+            } else {
+                Layout::new(padding_bytes, layout.align)
+            };
+
+            Some(self.padding_field(layout))
+        } else {
+            None
+        }
+    }
+
+    pub fn align_struct(&self, layout: Layout) -> Option<ast::StructField> {
+        if self.max_field_align < layout.align &&
+           layout.align <= mem::size_of::<*mut ()>() {
+            let ty = BlobTyBuilder::new(Layout::new(0, layout.align)).build();
+
+            Some(StructFieldBuilder::named("__bindgen_align")
+                .pub_()
+                .build_ty(ty))
+        } else {
+            None
+        }
+    }
+
+    fn padding_bytes(&self, layout: Layout) -> usize {
+        align_to(self.latest_offset, layout.align) - self.latest_offset
+    }
+
+    fn padding_field(&mut self, layout: Layout) -> ast::StructField {
+        let ty = BlobTyBuilder::new(layout).build();
+        let padding_count = self.padding_count;
+
+        self.padding_count += 1;
+
+        let padding_field_name = format!("__bindgen_padding_{}", padding_count);
+
+        self.max_field_align = cmp::max(self.max_field_align, layout.align);
+
+        StructFieldBuilder::named(padding_field_name).pub_().build_ty(ty)
+    }
+
+    /// Returns whether the new field is known to merge with a bitfield.
+    ///
+    /// This is just to avoid doing the same check also in pad_field.
+    fn align_to_latest_field(&mut self, new_field_layout: Layout) -> bool {
+        if self.comp.packed() {
+            // Skip to align fields when packed.
+            return false;
+        }
+
+        let layout = match self.latest_field_layout {
+            Some(l) => l,
+            None => return false,
+        };
+
+        // If it was, we may or may not need to align, depending on what the
+        // current field alignment and the bitfield size and alignment are.
+        debug!("align_to_bitfield? {}: {:?} {:?}", self.last_field_was_bitfield,
+               layout, new_field_layout);
+
+        if self.last_field_was_bitfield &&
+            new_field_layout.align <= layout.size % layout.align &&
+            new_field_layout.size <= layout.size % layout.align {
+            // The new field will be coalesced into some of the remaining bits.
+            //
+            // FIXME(emilio): I think this may not catch everything?
+            debug!("Will merge with bitfield");
+            return true;
+        }
+
+        // Else, just align the obvious way.
+        self.latest_offset += self.padding_bytes(layout);
+        return false;
+    }
+}
--- a/third_party/rust/bindgen/src/ir/comp.rs
+++ b/third_party/rust/bindgen/src/ir/comp.rs
@@ -1,17 +1,17 @@
 //! Compound types (unions and structs) in our intermediate representation.
 
 use super::annotations::Annotations;
 use super::context::{BindgenContext, ItemId};
-use super::derive::{CanDeriveCopy, CanDeriveDebug};
+use super::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault};
 use super::item::Item;
 use super::layout::Layout;
-use super::ty::Type;
-use super::type_collector::{ItemSet, TypeCollector};
+use super::traversal::{EdgeKind, Trace, Tracer};
+use super::ty::{TemplateDeclaration, Type};
 use clang;
 use parse::{ClangItemParser, ParseError};
 use std::cell::Cell;
 
 /// The kind of compound type.
 #[derive(Debug, Copy, Clone, PartialEq)]
 pub enum CompKind {
     /// A struct.
@@ -97,34 +97,38 @@ pub struct Field {
     /// The doc comment on the field if any.
     comment: Option<String>,
     /// Annotations for this field, or the default.
     annotations: Annotations,
     /// If this field is a bitfield, and how many bits does it contain if it is.
     bitfield: Option<u32>,
     /// If the C++ field is marked as `mutable`
     mutable: bool,
+    /// The offset of the field (in bits)
+    offset: Option<usize>,
 }
 
 impl Field {
     /// Construct a new `Field`.
     pub fn new(name: Option<String>,
                ty: ItemId,
                comment: Option<String>,
                annotations: Option<Annotations>,
                bitfield: Option<u32>,
-               mutable: bool)
+               mutable: bool,
+               offset: Option<usize>)
                -> Field {
         Field {
             name: name,
             ty: ty,
             comment: comment,
             annotations: annotations.unwrap_or_default(),
             bitfield: bitfield,
             mutable: mutable,
+            offset: offset,
         }
     }
 
     /// Get the name of this field.
     pub fn name(&self) -> Option<&str> {
         self.name.as_ref().map(|n| &**n)
     }
 
@@ -147,26 +151,39 @@ impl Field {
     pub fn is_mutable(&self) -> bool {
         self.mutable
     }
 
     /// Get the annotations for this field.
     pub fn annotations(&self) -> &Annotations {
         &self.annotations
     }
+
+    /// The offset of the field (in bits)
+    pub fn offset(&self) -> Option<usize> {
+        self.offset
+    }
 }
 
 impl CanDeriveDebug for Field {
     type Extra = ();
 
     fn can_derive_debug(&self, ctx: &BindgenContext, _: ()) -> bool {
         self.ty.can_derive_debug(ctx, ())
     }
 }
 
+impl CanDeriveDefault for Field {
+    type Extra = ();
+
+    fn can_derive_default(&self, ctx: &BindgenContext, _: ()) -> bool {
+        self.ty.can_derive_default(ctx, ())
+    }
+}
+
 impl<'a> CanDeriveCopy<'a> for Field {
     type Extra = ();
 
     fn can_derive_copy(&self, ctx: &BindgenContext, _: ()) -> bool {
         self.ty.can_derive_copy(ctx, ())
     }
 
     fn can_derive_copy_in_array(&self, ctx: &BindgenContext, _: ()) -> bool {
@@ -267,31 +284,32 @@ pub struct CompInfo {
 
     /// If this type has a template parameter which is not a type (e.g.: a
     /// size_t)
     has_non_type_template_params: bool,
 
     /// Whether this struct layout is packed.
     packed: bool,
 
-    /// Whether this struct is anonymous.
-    is_anonymous: bool,
-
     /// 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>,
 
     /// Used to indicate when a struct has been forward declared. Usually used
     /// in headers so that APIs can't modify them directly.
     is_forward_declaration: bool,
 }
@@ -309,19 +327,19 @@ impl CompInfo {
             ref_template: None,
             inner_types: vec![],
             inner_vars: vec![],
             has_vtable: false,
             has_destructor: false,
             has_nonempty_base: false,
             has_non_type_template_params: false,
             packed: false,
-            is_anonymous: 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() &&
@@ -386,20 +404,19 @@ impl CompInfo {
     /// This is called as a fallback under some circumstances where LLVM doesn't
     /// give us the correct layout.
     ///
     /// If we're a union without known layout, we try to compute it from our
     /// members. This is not ideal, but clang fails to report the size for these
     /// kind of unions, see test/headers/template_union.hpp
     pub fn layout(&self, ctx: &BindgenContext) -> Option<Layout> {
         use std::cmp;
-
         // We can't do better than clang here, sorry.
         if self.kind == CompKind::Struct {
-            return None;
+            return None
         }
 
         let mut max_size = 0;
         let mut max_align = 0;
         for field in &self.fields {
             let field_layout = ctx.resolve_type(field.ty)
                 .layout(ctx);
 
@@ -488,22 +505,19 @@ impl CompInfo {
         let mut ci = CompInfo::new(kind);
         ci.is_forward_declaration =
             location.map_or(true, |cur| match cur.kind() {
                 CXCursor_StructDecl |
                 CXCursor_UnionDecl |
                 CXCursor_ClassDecl => !cur.is_definition(),
                 _ => false,
             });
-        ci.is_anonymous = cursor.is_anonymous();
         ci.template_args = match ty.template_args() {
-            // In forward declarations and not specializations,
-            // etc, they are in
-            // the ast, we'll meet them in
-            // CXCursor_TemplateTypeParameter
+            // In forward declarations and not specializations, etc, they are in
+            // the ast, we'll meet them in CXCursor_TemplateTypeParameter
             None => vec![],
             Some(arg_types) => {
                 let num_arg_types = arg_types.len();
                 let mut specialization = true;
 
                 let args = arg_types.filter(|t| t.kind() != CXType_Invalid)
                     .filter_map(|t| if t.spelling()
                         .starts_with("type-parameter") {
@@ -524,71 +538,73 @@ impl CompInfo {
         };
 
         ci.ref_template = cursor.specialized()
             .and_then(|c| Item::parse(c, None, ctx).ok());
 
         let mut maybe_anonymous_struct_field = None;
         cursor.visit(|cur| {
             if cur.kind() != CXCursor_FieldDecl {
-                if let Some((ty, _)) = maybe_anonymous_struct_field {
-                    let field = Field::new(None, ty, None, None, None, false);
+                if let Some((ty, _, offset)) =
+                    maybe_anonymous_struct_field.take() {
+                    let field =
+                        Field::new(None, ty, None, None, None, false, offset);
                     ci.fields.push(field);
                 }
-                maybe_anonymous_struct_field = None;
             }
 
             match cur.kind() {
                 CXCursor_FieldDecl => {
-                    match maybe_anonymous_struct_field.take() {
-                        Some((ty, clang_ty)) => {
-                            let mut used = false;
-                            cur.visit(|child| {
-                                if child.cur_type() == clang_ty {
-                                    used = true;
-                                }
-                                CXChildVisit_Continue
-                            });
-                            if !used {
-                                let field = Field::new(None,
-                                                       ty,
-                                                       None,
-                                                       None,
-                                                       None,
-                                                       false);
-                                ci.fields.push(field);
+                    if let Some((ty, clang_ty, offset)) =
+                        maybe_anonymous_struct_field.take() {
+                        let mut used = false;
+                        cur.visit(|child| {
+                            if child.cur_type() == clang_ty {
+                                used = true;
                             }
+                            CXChildVisit_Continue
+                        });
+                        if !used {
+                            let field = Field::new(None,
+                                                   ty,
+                                                   None,
+                                                   None,
+                                                   None,
+                                                   false,
+                                                   offset);
+                            ci.fields.push(field);
                         }
-                        None => {}
                     }
 
                     let bit_width = cur.bit_width();
                     let field_type = Item::from_ty_or_ref(cur.cur_type(),
                                                           Some(cur),
                                                           Some(potential_id),
                                                           ctx);
 
                     let comment = cur.raw_comment();
                     let annotations = Annotations::new(&cur);
                     let name = cur.spelling();
                     let is_mutable = cursor.is_mutable_field();
+                    let offset = cur.offset_of_field().ok();
 
                     // Name can be empty if there are bitfields, for example,
                     // see tests/headers/struct_with_bitfields.h
                     assert!(!name.is_empty() || bit_width.is_some(),
                             "Empty field name?");
 
                     let name = if name.is_empty() { None } else { Some(name) };
 
                     let field = Field::new(name,
                                            field_type,
                                            comment,
                                            annotations,
                                            bit_width,
-                                           is_mutable);
+                                           is_mutable,
+                                           offset);
                     ci.fields.push(field);
 
                     // No we look for things like attributes and stuff.
                     cur.visit(|cur| {
                         if cur.kind() == CXCursor_UnexposedAttr {
                             ci.found_unknown_attr = true;
                         }
                         CXChildVisit_Continue
@@ -600,27 +616,38 @@ impl CompInfo {
                 }
                 CXCursor_EnumDecl |
                 CXCursor_TypeAliasDecl |
                 CXCursor_TypedefDecl |
                 CXCursor_StructDecl |
                 CXCursor_UnionDecl |
                 CXCursor_ClassTemplate |
                 CXCursor_ClassDecl => {
+                    // We can find non-semantic children here, clang uses a
+                    // StructDecl to note incomplete structs that hasn't been
+                    // forward-declared before, see:
+                    //
+                    // https://github.com/servo/rust-bindgen/issues/482
+                    if cur.semantic_parent() != cursor {
+                        return CXChildVisit_Continue;
+                    }
+
                     let inner = Item::parse(cur, Some(potential_id), ctx)
                         .expect("Inner ClassDecl");
-                    if !ci.inner_types.contains(&inner) {
-                        ci.inner_types.push(inner);
-                    }
+
+                    ci.inner_types.push(inner);
+
                     // A declaration of an union or a struct without name could
                     // also be an unnamed field, unfortunately.
                     if cur.spelling().is_empty() &&
                        cur.kind() != CXCursor_EnumDecl {
                         let ty = cur.cur_type();
-                        maybe_anonymous_struct_field = Some((inner, ty));
+                        let offset = cur.offset_of_field().ok();
+                        maybe_anonymous_struct_field =
+                            Some((inner, ty, offset));
                     }
                 }
                 CXCursor_PackedAttr => {
                     ci.packed = true;
                 }
                 CXCursor_TemplateTypeParameter => {
                     // Yes! You can arrive here with an empty template parameter
                     // name! Awesome, isn't it?
@@ -743,18 +770,18 @@ impl CompInfo {
                           cur.kind(),
                           cursor.spelling(),
                           cur.location());
                 }
             }
             CXChildVisit_Continue
         });
 
-        if let Some((ty, _)) = maybe_anonymous_struct_field {
-            let field = Field::new(None, ty, None, None, None, false);
+        if let Some((ty, _, offset)) = maybe_anonymous_struct_field {
+            let field = Field::new(None, ty, None, None, None, false, offset);
             ci.fields.push(field);
         }
 
         Ok(ci)
     }
 
     fn kind_from_cursor(cursor: &clang::Cursor)
                         -> Result<CompKind, ParseError> {
@@ -838,16 +865,26 @@ impl CompInfo {
     }
 
     /// Returns true if compound type has been forward declared
     pub fn is_forward_declaration(&self) -> bool {
         self.is_forward_declaration
     }
 }
 
+impl TemplateDeclaration for CompInfo {
+    fn template_params(&self, _ctx: &BindgenContext) -> Option<Vec<ItemId>> {
+        if self.template_args.is_empty() {
+            None
+        } else {
+            Some(self.template_args.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() {
@@ -887,16 +924,62 @@ impl CanDeriveDebug for CompInfo {
         };
 
         self.detect_derive_debug_cycle.set(false);
 
         can_derive_debug
     }
 }
 
+impl CanDeriveDefault for CompInfo {
+    type Extra = Option<Layout>;
+
+    fn can_derive_default(&self,
+                          ctx: &BindgenContext,
+                          layout: 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 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_default_cycle.set(true);
+
+        let can_derive_default = !self.has_vtable(ctx) &&
+                                 !self.needs_explicit_vtable(ctx) &&
+                                 self.base_members
+            .iter()
+            .all(|base| base.ty.can_derive_default(ctx, ())) &&
+                                 self.template_args
+            .iter()
+            .all(|id| id.can_derive_default(ctx, ())) &&
+                                 self.fields
+            .iter()
+            .all(|f| f.can_derive_default(ctx, ())) &&
+                                 self.ref_template
+            .map_or(true, |id| id.can_derive_default(ctx, ()));
+
+        self.detect_derive_default_cycle.set(false);
+
+        can_derive_default
+    }
+}
+
 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() {
@@ -939,49 +1022,60 @@ impl<'a> CanDeriveCopy<'a> for CompInfo 
     fn can_derive_copy_in_array(&self,
                                 ctx: &BindgenContext,
                                 extra: (&Item, Option<Layout>))
                                 -> bool {
         self.can_derive_copy(ctx, extra)
     }
 }
 
-impl TypeCollector for CompInfo {
+impl Trace for CompInfo {
     type Extra = Item;
 
-    fn collect_types(&self,
-                     context: &BindgenContext,
-                     types: &mut ItemSet,
-                     item: &Item) {
+    fn trace<T>(&self, context: &BindgenContext, tracer: &mut T, item: &Item)
+        where T: Tracer,
+    {
+        // TODO: We should properly distinguish template instantiations from
+        // template declarations at the type level. Why are some template
+        // instantiations represented here instead of as
+        // TypeKind::TemplateInstantiation?
         if let Some(template) = self.specialized_template() {
-            types.insert(template);
-        }
-
-        let applicable_template_args = item.applicable_template_args(context);
-        for arg in applicable_template_args {
-            types.insert(arg);
+            // This is an instantiation of a template declaration with concrete
+            // template type arguments.
+            tracer.visit(template);
+            let args = item.applicable_template_args(context);
+            for a in args {
+                tracer.visit(a);
+            }
+        } else {
+            let params = item.applicable_template_args(context);
+            // This is a template declaration with abstract template type
+            // parameters.
+            for p in params {
+                tracer.visit_kind(p, EdgeKind::TemplateParameterDefinition);
+            }
         }
 
         for base in self.base_members() {
-            types.insert(base.ty);
+            tracer.visit(base.ty);
         }
 
         for field in self.fields() {
-            types.insert(field.ty());
+            tracer.visit(field.ty());
         }
 
         for &ty in self.inner_types() {
-            types.insert(ty);
+            tracer.visit(ty);
         }
 
         for &var in self.inner_vars() {
-            types.insert(var);
+            tracer.visit(var);
         }
 
         for method in self.methods() {
-            types.insert(method.signature);
+            tracer.visit(method.signature);
         }
 
         for &ctor in self.constructors() {
-            types.insert(ctor);
+            tracer.visit(ctor);
         }
     }
 }
--- a/third_party/rust/bindgen/src/ir/context.rs
+++ b/third_party/rust/bindgen/src/ir/context.rs
@@ -1,27 +1,31 @@
 //! Common context that is passed around during parsing and codegen.
 
-use super::derive::{CanDeriveCopy, CanDeriveDebug};
+use super::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault};
 use super::int::IntKind;
-use super::item::{Item, ItemCanonicalPath};
+use super::item::{Item, ItemCanonicalPath, ItemSet};
 use super::item_kind::ItemKind;
 use super::module::{Module, ModuleKind};
-use super::ty::{FloatKind, Type, TypeKind};
-use super::type_collector::{ItemSet, TypeCollector};
+use super::traversal::{self, Edge, ItemTraversal, Trace};
+use super::ty::{FloatKind, TemplateDeclaration, Type, TypeKind};
 use BindgenOptions;
 use cexpr;
 use chooser::TypeChooser;
 use clang::{self, Cursor};
+use clang_sys;
 use parse::ClangItemParser;
 use std::borrow::Cow;
 use std::cell::Cell;
-use std::collections::{HashMap, VecDeque, hash_map};
+use std::collections::{HashMap, hash_map};
 use std::collections::btree_map::{self, BTreeMap};
 use std::fmt;
+use std::fs::File;
+use std::io::{self, Write};
+use std::iter::IntoIterator;
 use syntax::ast::Ident;
 use syntax::codemap::{DUMMY_SP, Span};
 use syntax::ext::base::ExtCtxt;
 
 /// A single identifier for an item.
 ///
 /// TODO: Build stronger abstractions on top of this, like TypeId(ItemId)?
 #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
@@ -37,16 +41,24 @@ impl ItemId {
 impl CanDeriveDebug for ItemId {
     type Extra = ();
 
     fn can_derive_debug(&self, ctx: &BindgenContext, _: ()) -> bool {
         ctx.resolve_item(*self).can_derive_debug(ctx, ())
     }
 }
 
+impl CanDeriveDefault 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 {
     type Extra = ();
 
     fn can_derive_copy(&self, ctx: &BindgenContext, _: ()) -> bool {
         ctx.resolve_item(*self).can_derive_copy(ctx, ())
     }
 
     fn can_derive_copy_in_array(&self, ctx: &BindgenContext, _: ()) -> bool {
@@ -107,19 +119,17 @@ pub struct BindgenContext<'ctx> {
     /// struct c { struct c* next; };
     ///
     /// This means effectively, that a type has a potential ID before knowing if
     /// it's a correct type. But that's not important in practice.
     ///
     /// We could also use the `types` HashMap, but my intention with it is that
     /// only valid types and declarations end up there, and this could
     /// potentially break that assumption.
-    ///
-    /// FIXME: Should not be public, though... meh.
-    pub currently_parsed_types: Vec<(Cursor, ItemId)>,
+    currently_parsed_types: Vec<PartialType>,
 
     /// A HashSet with all the already parsed macro names. This is done to avoid
     /// hard errors while parsing duplicated macros, as well to allow macro
     /// expression parsing.
     parsed_macros: HashMap<Vec<u8>, cexpr::expr::EvalResult>,
 
     /// The active replacements collected from replaces="xxx" annotations.
     replacements: HashMap<Vec<String>, ItemId>,
@@ -138,16 +148,23 @@ pub struct BindgenContext<'ctx> {
 
     /// The options given by the user via cli or other medium.
     options: BindgenOptions,
 
     /// Whether a bindgen complex was generated
     generated_bindegen_complex: Cell<bool>,
 }
 
+/// A traversal of whitelisted items.
+pub type WhitelistedItems<'ctx, 'gen> = ItemTraversal<'ctx,
+                                                      'gen,
+                                                      ItemSet,
+                                                      Vec<ItemId>,
+                                                      fn(Edge) -> bool>;
+
 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 =
@@ -180,16 +197,36 @@ impl<'ctx> BindgenContext<'ctx> {
             generated_bindegen_complex: Cell::new(false),
         };
 
         me.add_item(root_module, None, None);
 
         me
     }
 
+    /// Get the stack of partially parsed types that we are in the middle of
+    /// parsing.
+    pub fn currently_parsed_types(&self) -> &[PartialType] {
+        &self.currently_parsed_types[..]
+    }
+
+    /// Begin parsing the given partial type, and push it onto the
+    /// `currently_parsed_types` stack so that we won't infinite recurse if we
+    /// run into a reference to it while parsing it.
+    pub fn begin_parsing(&mut self, partial_ty: PartialType) {
+        self.currently_parsed_types.push(partial_ty);
+    }
+
+    /// Finish parsing the current partial type, pop it off the
+    /// `currently_parsed_types` stack, and return it.
+    pub fn finish_parsing(&mut self) -> PartialType {
+        self.currently_parsed_types.pop()
+            .expect("should have been parsing a type, if we finished parsing a type")
+    }
+
     /// Get the user-provided type chooser by reference, if any.
     pub fn type_chooser(&self) -> Option<&TypeChooser> {
         self.options().type_chooser.as_ref().map(|t| &**t)
     }
 
     /// Define a new item.
     ///
     /// This inserts it into the internal items set, and its type into the
@@ -505,33 +542,24 @@ impl<'ctx> BindgenContext<'ctx> {
             for _ in self.assert_no_dangling_item_traversal() {
                 // The iterator's next method does the asserting for us.
             }
         }
     }
 
     fn assert_no_dangling_item_traversal<'me>
         (&'me self)
-         -> AssertNoDanglingItemIter<'me, 'ctx> {
+         -> traversal::AssertNoDanglingItemsTraversal<'me, 'ctx> {
         assert!(self.in_codegen_phase());
         assert!(self.current_module == self.root_module);
 
-        let mut roots = self.items().map(|(&id, _)| id);
-
-        let mut seen = BTreeMap::<ItemId, ItemId>::new();
-        let next_child = roots.next().map(|id| id).unwrap();
-        seen.insert(next_child, next_child);
-
-        let to_iterate = seen.iter().map(|(&id, _)| id).rev().collect();
-
-        AssertNoDanglingItemIter {
-            ctx: self,
-            seen: seen,
-            to_iterate: to_iterate,
-        }
+        let roots = self.items().map(|(&id, _)| id);
+        traversal::AssertNoDanglingItemsTraversal::new(self,
+                                                       roots,
+                                                       traversal::all_edges)
     }
 
     // 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.
     //
@@ -587,213 +615,343 @@ impl<'ctx> BindgenContext<'ctx> {
         }
     }
 
     /// Get the current module.
     pub fn current_module(&self) -> ItemId {
         self.current_module
     }
 
-    /// This is one of the hackiest methods in all the parsing code. This method
-    /// is used to allow having templates with another argument names instead of
-    /// the canonical ones.
+    /// Given a cursor pointing to the location of a template instantiation,
+    /// return a tuple of the form `(declaration_cursor, declaration_id,
+    /// num_expected_template_args)`.
+    ///
+    /// Note that `declaration_id` is not guaranteed to be in the context's item
+    /// set! It is possible that it is a partial type that we are still in the
+    /// middle of parsign.
+    fn get_declaration_info_for_template_instantiation
+        (&self,
+         instantiation: &Cursor)
+         -> Option<(Cursor, ItemId, usize)> {
+        instantiation.cur_type()
+            .canonical_declaration(Some(instantiation))
+            .and_then(|canon_decl| {
+                self.get_resolved_type(&canon_decl)
+                    .and_then(|template_decl_id| {
+                        template_decl_id.num_template_params(self)
+                            .map(|num_params| {
+                                (*canon_decl.cursor(),
+                                 template_decl_id,
+                                 num_params)
+                            })
+                    })
+            })
+            .or_else(|| {
+                // If we haven't already parsed the declaration of
+                // the template being instantiated, then it *must*
+                // be on the stack of types we are currently
+                // parsing. If it wasn't then clang would have
+                // already errored out before we started
+                // constructing our IR because you can't instantiate
+                // a template until it is fully defined.
+                instantiation.referenced()
+                    .and_then(|referenced| {
+                        self.currently_parsed_types()
+                            .iter()
+                            .find(|partial_ty| *partial_ty.decl() == referenced)
+                            .cloned()
+                    })
+                    .and_then(|template_decl| {
+                        template_decl.num_template_params(self)
+                            .map(|num_template_params| {
+                                (*template_decl.decl(),
+                                 template_decl.id(),
+                                 num_template_params)
+                            })
+                    })
+            })
+    }
+
+    /// Parse a template instantiation, eg `Foo<int>`.
     ///
     /// This is surprisingly difficult to do with libclang, due to the fact that
-    /// partial template specializations don't provide explicit template
-    /// argument information.
+    /// it doesn't provide explicit template argument information, except for
+    /// function template declarations(!?!??!).
     ///
-    /// The only way to do this as far as I know, is inspecting manually the
-    /// AST, looking for TypeRefs inside. This, unfortunately, doesn't work for
+    /// The only way to do this is manually inspecting the AST and looking for
+    /// TypeRefs and TemplateRefs inside. This, unfortunately, doesn't work for
     /// more complex cases, see the comment on the assertion below.
     ///
-    /// To see an example of what this handles:
+    /// To add insult to injury, the AST itself has structure that doesn't make
+    /// sense. Sometimes `Foo<Bar<int>>` has an AST with nesting like you might
+    /// expect: `(Foo (Bar (int)))`. Other times, the AST we get is completely
+    /// flat: `(Foo Bar int)`.
+    ///
+    /// To see an example of what this method handles:
     ///
     /// ```c++
-    ///     template<typename T>
-    ///     class Incomplete {
-    ///       T p;
-    ///     };
+    /// template<typename T>
+    /// class Incomplete {
+    ///   T p;
+    /// };
     ///
-    ///     template<typename U>
-    ///     class Foo {
-    ///       Incomplete<U> bar;
-    ///     };
+    /// template<typename U>
+    /// class Foo {
+    ///   Incomplete<U> bar;
+    /// };
     /// ```
-    fn build_template_wrapper(&mut self,
-                              with_id: ItemId,
-                              wrapping: ItemId,
-                              parent_id: ItemId,
-                              ty: &clang::Type,
-                              location: clang::Cursor,
-                              declaration: clang::Cursor)
-                              -> ItemId {
-        use clang_sys::*;
-        let mut args = vec![];
-        location.visit(|c| {
-            if c.kind() == CXCursor_TypeRef {
-                // The `with_id` id will potentially end up unused if we give up
-                // on this type (for example, its a tricky partial template
-                // specialization), so if we pass `with_id` as the parent, it is
-                // potentially a dangling reference. Instead, use the canonical
-                // template declaration as the parent. It is already parsed and
-                // has a known-resolvable `ItemId`.
-                let new_ty = Item::from_ty_or_ref(c.cur_type(),
-                                                  Some(c),
-                                                  Some(wrapping),
-                                                  self);
-                args.push(new_ty);
-            }
-            CXChildVisit_Continue
-        });
-
-        let item = {
-            let wrapping_type = self.resolve_type(wrapping);
-            if let TypeKind::Comp(ref ci) = *wrapping_type.kind() {
-                let old_args = ci.template_args();
+    fn instantiate_template(&mut self,
+                            with_id: ItemId,
+                            template: ItemId,
+                            parent_id: ItemId,
+                            ty: &clang::Type,
+                            location: clang::Cursor)
+                            -> Option<ItemId> {
+        use clang_sys;
 
-                // The following assertion actually fails with partial template
-                // specialization. But as far as I know there's no way at all to
-                // grab the specialized types from neither the AST or libclang,
-                // which sucks. The same happens for specialized type alias
-                // template declarations, where we have that ugly hack up there.
-                //
-                // This flaw was already on the old parser, but I now think it
-                // has no clear solution (apart from patching libclang to
-                // somehow expose them, of course).
-                //
-                // For an easy example in which there's no way at all of getting
-                // the `int` type, except manually parsing the spelling:
-                //
-                //     template<typename T, typename U>
-                //     class Incomplete {
-                //       T d;
-                //       U p;
-                //     };
-                //
-                //     template<typename U>
-                //     class Foo {
-                //       Incomplete<U, int> bar;
-                //     };
-                //
-                // debug_assert_eq!(old_args.len(), args.len());
-                //
-                // That being said, this is not so common, so just error! and
-                // hope for the best, returning the previous type, who knows.
-                if old_args.len() != args.len() {
-                    error!("Found partial template specialization, \
-                            expect dragons!");
-                    return wrapping;
-                }
-            } else {
-                assert_eq!(declaration.kind(),
-                           ::clang_sys::CXCursor_TypeAliasTemplateDecl,
-                           "Expected wrappable type");
+        let num_expected_args = match self.resolve_type(template)
+            .num_template_params(self) {
+            Some(n) => n,
+            None => {
+                warn!("Tried to instantiate a template for which we could not \
+                       determine any template parameters");
+                return None;
             }
-
-            let type_kind = TypeKind::TemplateRef(wrapping, 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());
-            Item::new(with_id, None, None, parent_id, ItemKind::Type(ty))
         };
 
+        let mut args = vec![];
+        let mut found_const_arg = false;
+        let mut children = location.collect_children();
+
+        if children.iter().all(|c| !c.has_children()) {
+            // This is insanity... If clang isn't giving us a properly nested
+            // AST for which template arguments belong to which template we are
+            // instantiating, we'll need to construct it ourselves. However,
+            // there is an extra `NamespaceRef, NamespaceRef, ..., TemplateRef`
+            // representing a reference to the outermost template declaration
+            // that we need to filter out of the children. We need to do this
+            // filtering because we already know which template declaration is
+            // being specialized via the `location`'s type, and if we do not
+            // filter it out, we'll add an extra layer of template instantiation
+            // on accident.
+            let idx = children.iter()
+                .position(|c| c.kind() == clang_sys::CXCursor_TemplateRef);
+            if let Some(idx) = idx {
+                if children.iter()
+                    .take(idx)
+                    .all(|c| c.kind() == clang_sys::CXCursor_NamespaceRef) {
+                    children = children.into_iter().skip(idx + 1).collect();
+                }
+            }
+        }
+
+        for child in children.iter().rev() {
+            match child.kind() {
+                clang_sys::CXCursor_TypeRef |
+                clang_sys::CXCursor_TypedefDecl |
+                clang_sys::CXCursor_TypeAliasDecl => {
+                    // The `with_id` id will potentially end up unused if we give up
+                    // on this type (for example, because it has const value
+                    // template args), so if we pass `with_id` as the parent, it is
+                    // potentially a dangling reference. Instead, use the canonical
+                    // template declaration as the parent. It is already parsed and
+                    // has a known-resolvable `ItemId`.
+                    let ty = Item::from_ty_or_ref(child.cur_type(),
+                                                  Some(*child),
+                                                  Some(template),
+                                                  self);
+                    args.push(ty);
+                }
+                clang_sys::CXCursor_TemplateRef => {
+                    let (template_decl_cursor, template_decl_id, num_expected_template_args) =
+                        match self.get_declaration_info_for_template_instantiation(child) {
+                            Some(info) => info,
+                            None => return None,
+                        };
+
+                    if num_expected_template_args == 0 ||
+                       child.has_at_least_num_children(num_expected_template_args) {
+                        // Do a happy little parse. See comment in the TypeRef
+                        // match arm about parent IDs.
+                        let ty = Item::from_ty_or_ref(child.cur_type(),
+                                                      Some(*child),
+                                                      Some(template),
+                                                      self);
+                        args.push(ty);
+                    } else {
+                        // This is the case mentioned in the doc comment where
+                        // clang gives us a flattened AST and we have to
+                        // reconstruct which template arguments go to which
+                        // instantiation :(
+                        let args_len = args.len();
+                        if args_len < num_expected_template_args {
+                            warn!("Found a template instantiation without \
+                                   enough template arguments");
+                            return None;
+                        }
+
+                        let mut sub_args: Vec<_> =
+                            args.drain(args_len - num_expected_template_args..)
+                                .collect();
+                        sub_args.reverse();
+
+                        let sub_name = Some(template_decl_cursor.spelling());
+                        let sub_kind =
+                            TypeKind::TemplateInstantiation(template_decl_id,
+                                                            sub_args);
+                        let sub_ty = Type::new(sub_name,
+                                               template_decl_cursor.cur_type()
+                                                   .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,
+                                                 ItemKind::Type(sub_ty));
+
+                        // Bypass all the validations in add_item explicitly.
+                        debug!("instantiate_template: inserting nested \
+                                instantiation item: {:?}",
+                               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);
+                    found_const_arg = true;
+                }
+            }
+        }
+
+        if found_const_arg {
+            // This is a dependently typed template instantiation. That is, an
+            // instantiation of a template with one or more const values as
+            // template arguments, rather than only types as template
+            // arguments. For example, `Foo<true, 5>` versus `Bar<bool, int>`.
+            // We can't handle these instantiations, so just punt in this
+            // situation...
+            warn!("Found template instantiated with a const value; \
+                   bindgen can't handle this kind of template instantiation!");
+            return None;
+        }
+
+        if args.len() != num_expected_args {
+            warn!("Found a template with an unexpected number of template \
+                   arguments");
+            return None;
+        }
+
+        args.reverse();
+        let type_kind = TypeKind::TemplateInstantiation(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));
+
         // Bypass all the validations in add_item explicitly.
-        debug!("build_template_wrapper: inserting item: {:?}", item);
+        debug!("instantiate_template: inserting item: {:?}", item);
         debug_assert!(with_id == item.id());
         self.items.insert(with_id, item);
-        with_id
+        Some(with_id)
+    }
+
+    /// If we have already resolved the type for the given type declaration,
+    /// return its `ItemId`. Otherwise, return `None`.
+    fn get_resolved_type(&self,
+                         decl: &clang::CanonicalTypeDeclaration)
+                         -> Option<ItemId> {
+        self.types
+            .get(&TypeKey::Declaration(*decl.cursor()))
+            .or_else(|| {
+                decl.cursor()
+                    .usr()
+                    .and_then(|usr| self.types.get(&TypeKey::USR(usr)))
+            })
+            .cloned()
     }
 
     /// Looks up for an already resolved type, either because it's builtin, or
     /// because we already have it in the map.
     pub fn builtin_or_resolved_ty(&mut self,
                                   with_id: ItemId,
                                   parent_id: Option<ItemId>,
                                   ty: &clang::Type,
                                   location: Option<clang::Cursor>)
                                   -> Option<ItemId> {
         use clang_sys::{CXCursor_TypeAliasTemplateDecl, CXCursor_TypeRef};
         debug!("builtin_or_resolved_ty: {:?}, {:?}, {:?}",
                ty,
                location,
                parent_id);
-        let mut declaration = ty.declaration();
-        if !declaration.is_valid() {
-            if let Some(location) = location {
-                if location.is_template_like() {
-                    declaration = location;
-                }
-            }
-        }
-        let canonical_declaration = declaration.canonical();
-        if canonical_declaration.is_valid() {
-            let id = self.types
-                .get(&TypeKey::Declaration(canonical_declaration))
-                .map(|id| *id)
-                .or_else(|| {
-                    canonical_declaration.usr()
-                        .and_then(|usr| self.types.get(&TypeKey::USR(usr)))
-                        .map(|id| *id)
-                });
-            if let Some(id) = id {
+
+        if let Some(decl) = ty.canonical_declaration(location.as_ref()) {
+            if let Some(id) = self.get_resolved_type(&decl) {
                 debug!("Already resolved ty {:?}, {:?}, {:?} {:?}",
                        id,
-                       declaration,
+                       decl,
                        ty,
                        location);
-
-                // If the declaration existed, we *might* be done, but it's not
-                // the case for class templates, where the template arguments
-                // may vary.
+                // If the declaration already exists, then either:
                 //
-                // In this case, we create a TemplateRef with the new template
-                // arguments, pointing to the canonical template.
+                //   * the declaration is a template declaration of some sort,
+                //     and we are looking at an instantiation or specialization
+                //     of it, or
+                //   * we have already parsed and resolved this type, and
+                //     there's nothing left to do.
                 //
-                // Note that we only do it if parent_id is some, and we have a
-                // location for building the new arguments, the template
-                // argument names don't matter in the global context.
-                if declaration.is_template_like() &&
-                   *ty != canonical_declaration.cur_type() &&
+                // Note that we only do the former if the `parent_id` exists,
+                // and we have a location for building the new arguments. The
+                // template argument names don't matter in the global context.
+                if decl.cursor().is_template_like() &&
+                   *ty != decl.cursor().cur_type() &&
                    location.is_some() &&
                    parent_id.is_some() {
+                    let location = location.unwrap();
+                    let parent_id = parent_id.unwrap();
+
                     // 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.
                     //
                     // This is _tricky_, I know :(
-                    if declaration.kind() == CXCursor_TypeAliasTemplateDecl &&
-                       !location.unwrap().contains_cursor(CXCursor_TypeRef) &&
+                    if decl.cursor().kind() == CXCursor_TypeAliasTemplateDecl &&
+                       !location.contains_cursor(CXCursor_TypeRef) &&
                        ty.canonical_type().is_valid_and_exposed() {
                         return None;
                     }
 
-                    return Some(self.build_template_wrapper(with_id,
-                                                id,
-                                                parent_id.unwrap(),
-                                                ty,
-                                                location.unwrap(),
-                                                declaration));
+                    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));
             }
         }
 
         debug!("Not resolved, maybe builtin?");
-
-        // Else, build it.
-        self.build_builtin_ty(ty, declaration)
+        self.build_builtin_ty(ty)
     }
 
     // This is unfortunately a lot of bloat, but is needed to properly track
     // constness et. al.
     //
     // We should probably make the constness tracking separate, so it doesn't
     // bloat that much, but hey, we already bloat the heck out of builtin types.
     fn build_ty_wrapper(&mut self,
@@ -818,20 +976,17 @@ impl<'ctx> BindgenContext<'ctx> {
 
     /// Returns the next item id to be used for an item.
     pub fn next_item_id(&mut self) -> ItemId {
         let ret = self.next_item_id;
         self.next_item_id = ItemId(self.next_item_id.0 + 1);
         ret
     }
 
-    fn build_builtin_ty(&mut self,
-                        ty: &clang::Type,
-                        _declaration: Cursor)
-                        -> Option<ItemId> {
+    fn build_builtin_ty(&mut self, ty: &clang::Type) -> Option<ItemId> {
         use clang_sys::*;
         let type_kind = match ty.kind() {
             CXType_NullPtr => TypeKind::NullPtr,
             CXType_Void => TypeKind::Void,
             CXType_Bool => TypeKind::Int(IntKind::Bool),
             CXType_Int => TypeKind::Int(IntKind::Int),
             CXType_UInt => TypeKind::Int(IntKind::UInt),
             CXType_SChar | CXType_Char_S => TypeKind::Int(IntKind::Char),
@@ -951,16 +1106,43 @@ impl<'ctx> BindgenContext<'ctx> {
         self.options.opaque_types.matches(&path[1..].join("::"))
     }
 
     /// Get the options used to configure this bindgen context.
     pub fn options(&self) -> &BindgenOptions {
         &self.options
     }
 
+    /// Output graphviz dot file.
+    pub fn emit_ir_graphviz(&self, path: String) -> io::Result<()> {
+        let file = try!(File::create(path));
+        let mut dot_file = io::BufWriter::new(file);
+        writeln!(&mut dot_file, "digraph {{")?;
+
+        let mut err: Option<io::Result<_>> = None;
+
+        for (id, item) in self.items() {
+            writeln!(&mut dot_file, "{} {};", id.0, item.dot_attributes(self))?;
+
+            item.trace(self, &mut |sub_id: ItemId, _edge_kind| {
+                match writeln!(&mut dot_file, "{} -> {};", id.0, sub_id.as_usize()) {
+                    Ok(_) => {},
+                    Err(e) => err = Some(Err(e)),
+                }
+            }, &());
+
+            if err.is_some() {
+                return err.unwrap();
+            }
+        }
+
+        writeln!(&mut dot_file, "}}")?;
+        Ok(())
+    }
+
     /// Tokenizes a namespace cursor in order to get the name and kind of the
     /// namespace,
     fn tokenize_namespace(&self,
                           cursor: &clang::Cursor)
                           -> (Option<String>, ModuleKind) {
         assert_eq!(cursor.kind(),
                    ::clang_sys::CXCursor_Namespace,
                    "Be a nice person");
@@ -1042,18 +1224,17 @@ 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)
-                                  -> WhitelistedItemsIter<'me, 'ctx> {
+    pub fn whitelisted_items<'me>(&'me self) -> WhitelistedItems<'me, 'ctx> {
         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() &&
@@ -1108,28 +1289,29 @@ impl<'ctx> BindgenContext<'ctx> {
                         }
 
                         false
                     }
                 }
             })
             .map(|(&id, _)| id);
 
-        let seen: ItemSet = roots.collect();
-
-        // The .rev() preserves the expected ordering traversal, resulting in
-        // more stable-ish bindgen-generated names for anonymous types (like
+        // The reversal preserves the expected ordering of traversal, resulting
+        // in more stable-ish bindgen-generated names for anonymous types (like
         // unions).
-        let to_iterate = seen.iter().cloned().rev().collect();
+        let mut roots: Vec<_> = roots.collect();
+        roots.reverse();
 
-        WhitelistedItemsIter {
-            ctx: self,
-            seen: seen,
-            to_iterate: to_iterate,
-        }
+        let predicate = if self.options().whitelist_recursively {
+            traversal::all_edges
+        } else {
+            traversal::no_edges
+        };
+
+        WhitelistedItems::new(self, roots, predicate)
     }
 
     /// 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 {
@@ -1143,128 +1325,69 @@ impl<'ctx> BindgenContext<'ctx> {
     }
 
     /// Whether we need to generate the binden complex type
     pub fn need_bindegen_complex_type(&self) -> bool {
         self.generated_bindegen_complex.get()
     }
 }
 
-/// An iterator over whitelisted items.
-///
-/// See `BindgenContext::whitelisted_items` for more information.
-pub struct WhitelistedItemsIter<'ctx, 'gen>
-    where 'gen: 'ctx,
-{
-    ctx: &'ctx BindgenContext<'gen>,
-
-    /// The set of whitelisted items we have seen. If you think of traversing
-    /// whitelisted items like GC tracing, this is the mark bits, and contains
-    /// both black and gray items.
-    seen: ItemSet,
-
-    /// The set of whitelisted items that we have seen but have yet to iterate
-    /// over and collect transitive references from. To return to the GC analogy,
-    /// this is the mark stack, containing the set of gray items which we have
-    /// not finished tracing yet.
-    to_iterate: Vec<ItemId>,
+/// A type that we are in the middle of parsing.
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+pub struct PartialType {
+    decl: Cursor,
+    id: ItemId,
 }
 
-impl<'ctx, 'gen> Iterator for WhitelistedItemsIter<'ctx, 'gen>
-    where 'gen: 'ctx,
-{
-    type Item = ItemId;
-
-    fn next(&mut self) -> Option<Self::Item> {
-        let id = match self.to_iterate.pop() {
-            None => return None,
-            Some(id) => id,
-        };
+impl PartialType {
+    /// Construct a new `PartialType`.
+    pub fn new(decl: Cursor, id: ItemId) -> PartialType {
+        // assert!(decl == decl.canonical());
+        PartialType {
+            decl: decl,
+            id: id,
+        }
+    }
 
-        debug_assert!(self.seen.contains(&id));
-        debug_assert!(self.ctx.items.contains_key(&id));
-
-        if self.ctx.options().whitelist_recursively {
-            let mut sub_types = ItemSet::new();
-            id.collect_types(self.ctx, &mut sub_types, &());
+    /// The cursor pointing to this partial type's declaration location.
+    pub fn decl(&self) -> &Cursor {
+        &self.decl
+    }
 
-            for id in sub_types {
-                if self.seen.insert(id) {
-                    self.to_iterate.push(id);
-                }
-            }
-        }
-
-        Some(id)
+    /// The item ID allocated for this type. This is *NOT* a key for an entry in
+    /// the context's item set yet!
+    pub fn id(&self) -> ItemId {
+        self.id
     }
 }
 
-/// An iterator to find any dangling items.
-///
-/// See `BindgenContext::assert_no_dangling_item_traversal` for more
-/// information.
-pub struct AssertNoDanglingItemIter<'ctx, 'gen>
-    where 'gen: 'ctx,
-{
-    ctx: &'ctx BindgenContext<'gen>,
-    seen: BTreeMap<ItemId, ItemId>,
-    to_iterate: VecDeque<ItemId>,
-}
-
-impl<'ctx, 'gen> Iterator for AssertNoDanglingItemIter<'ctx, 'gen>
-    where 'gen: 'ctx,
-{
-    type Item = ItemId;
+impl TemplateDeclaration for PartialType {
+    fn template_params(&self, _ctx: &BindgenContext) -> Option<Vec<ItemId>> {
+        // Maybe at some point we will eagerly parse named types, but for now we
+        // don't and this information is unavailable.
+        None
+    }
 
-    fn next(&mut self) -> Option<Self::Item> {
-        let id = match self.to_iterate.pop_front() {
-            None => {
-                // We've traversed everything reachable from the previous
-                // root(s), see if we have any more roots.
-                match self.ctx
-                    .items()
-                    .filter(|&(id, _)| !self.seen.contains_key(id))
-                    .next()
-                    .map(|(id, _)| *id) {
-                    None => return None,
-                    Some(id) => {
-                        // This is a new root.
-                        self.seen.insert(id, id);
-                        id
-                    }
-                }
+    fn num_template_params(&self, _ctx: &BindgenContext) -> Option<usize> {
+        // Wouldn't it be nice if libclang would reliably give us this
+        // information‽
+        match self.decl().kind() {
+            clang_sys::CXCursor_ClassTemplate |
+            clang_sys::CXCursor_FunctionTemplate |
+            clang_sys::CXCursor_TypeAliasTemplateDecl => {
+                let mut num_params = 0;
+                self.decl().visit(|c| {
+                    match c.kind() {
+                        clang_sys::CXCursor_TemplateTypeParameter |
+                        clang_sys::CXCursor_TemplateTemplateParameter |
+                        clang_sys::CXCursor_NonTypeTemplateParameter => {
+                            num_params += 1;
+                        }
+                        _ => {}
+                    };
+                    clang_sys::CXChildVisit_Continue
+                });
+                Some(num_params)
             }
-            Some(id) => id,
-        };
-
-        let mut sub_types = ItemSet::new();
-        id.collect_types(self.ctx, &mut sub_types, &());
-
-        if self.ctx.resolve_item_fallible(id).is_none() {
-            let mut path = vec![];
-            let mut current = id;
-            loop {
-                let predecessor = *self.seen
-                    .get(&current)
-                    .expect("We know we found this item id, so it must have a \
-                            predecessor");
-                if predecessor == current {
-                    break;
-                }
-                path.push(predecessor);
-                current = predecessor;
-            }
-            path.reverse();
-            panic!("Found reference to dangling id = {:?}\nvia path = {:?}",
-                   id,
-                   path);
+            _ => None,
         }
-
-        for sub_id in sub_types {
-            if self.seen.insert(sub_id, id).is_none() {
-                // We've never visited this sub item before.
-                self.to_iterate.push_back(sub_id);
-            }
-        }
-
-        Some(id)
     }
 }
--- a/third_party/rust/bindgen/src/ir/derive.rs
+++ b/third_party/rust/bindgen/src/ir/derive.rs
@@ -60,8 +60,29 @@ pub trait CanDeriveCopy<'a> {
     /// is an error.
     ///
     /// That's the whole point of the existence of `can_derive_copy_in_array`.
     fn can_derive_copy_in_array(&'a self,
                                 ctx: &'a BindgenContext,
                                 extra: Self::Extra)
                                 -> bool;
 }
+
+/// 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 {
+    /// 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,
+                          ctx: &BindgenContext,
+                          extra: Self::Extra)
+                          -> bool;
+}
--- a/third_party/rust/bindgen/src/ir/enum_ty.rs
+++ b/third_party/rust/bindgen/src/ir/enum_ty.rs
@@ -94,17 +94,17 @@ impl Enum {
                     let custom_behavior = ctx.type_chooser()
                         .and_then(|t| {
                             t.enum_variant_behavior(type_name, &name, val)
                         })
                         .or_else(|| {
                             Annotations::new(&cursor)
                                 .and_then(|anno| if anno.hide() {
                                     Some(EnumVariantCustomBehavior::Hide)
-                                } else if 
+                                } else if
                                     anno.constify_enum_variant() {
                                     Some(EnumVariantCustomBehavior::Constify)
                                 } else {
                                     None
                                 })
                         });
 
                     let comment = cursor.raw_comment();
--- a/third_party/rust/bindgen/src/ir/function.rs
+++ b/third_party/rust/bindgen/src/ir/function.rs
@@ -1,14 +1,14 @@
 //! Intermediate representation for C/C++ functions and methods.
 
 use super::context::{BindgenContext, ItemId};
 use super::item::Item;
+use super::traversal::{Trace, Tracer};
 use super::ty::TypeKind;
-use super::type_collector::{ItemSet, TypeCollector};
 use clang;
 use clang_sys::CXCallingConv;
 use parse::{ClangItemParser, ClangSubItemParser, ParseError, ParseResult};
 use syntax::abi;
 
 /// A function declaration, with a signature, arguments, and argument names.
 ///
 /// The argument names vector must be the same length as the ones in the
@@ -68,28 +68,29 @@ pub struct FunctionSig {
     /// The type of the arguments, optionally with the name of the argument when
     /// declared.
     argument_types: Vec<(Option<String>, ItemId)>,
 
     /// Whether this function is variadic.
     is_variadic: bool,
 
     /// The ABI of this function.
-    abi: abi::Abi,
+    abi: Option<abi::Abi>,
 }
 
-fn get_abi(cc: CXCallingConv) -> abi::Abi {
+fn get_abi(cc: CXCallingConv) -> Option<abi::Abi> {
     use clang_sys::*;
     match cc {
-        CXCallingConv_Default => abi::Abi::C,
-        CXCallingConv_C => abi::Abi::C,
-        CXCallingConv_X86StdCall => abi::Abi::Stdcall,
-        CXCallingConv_X86FastCall => abi::Abi::Fastcall,
-        CXCallingConv_AAPCS => abi::Abi::Aapcs,
-        CXCallingConv_X86_64Win64 => abi::Abi::Win64,
+        CXCallingConv_Default => Some(abi::Abi::C),
+        CXCallingConv_C => Some(abi::Abi::C),
+        CXCallingConv_X86StdCall => Some(abi::Abi::Stdcall),
+        CXCallingConv_X86FastCall => Some(abi::Abi::Fastcall),
+        CXCallingConv_AAPCS => Some(abi::Abi::Aapcs),
+        CXCallingConv_X86_64Win64 => Some(abi::Abi::Win64),
+        CXCallingConv_Invalid => None,
         other => panic!("unsupported calling convention: {:?}", other),
     }
 }
 
 /// Get the mangled name for the cursor's referent.
 pub fn cursor_mangling(cursor: &clang::Cursor) -> Option<String> {
     // We early return here because libclang may crash in some case
     // if we pass in a variable inside a partial specialized template.
@@ -111,17 +112,17 @@ pub fn cursor_mangling(cursor: &clang::C
     Some(mangling)
 }
 
 impl FunctionSig {
     /// Construct a new function signature.
     pub fn new(return_type: ItemId,
                arguments: Vec<(Option<String>, ItemId)>,
                is_variadic: bool,
-               abi: abi::Abi)
+               abi: Option<abi::Abi>)
                -> Self {
         FunctionSig {
             return_type: return_type,
             argument_types: arguments,
             is_variadic: is_variadic,
             abi: abi,
         }
     }
@@ -149,17 +150,18 @@ impl FunctionSig {
             *cursor
         } else {
             ty.declaration()
         };
 
         let mut args: Vec<_> = match cursor.kind() {
             CXCursor_FunctionDecl |
             CXCursor_Constructor |
-            CXCursor_CXXMethod => {
+            CXCursor_CXXMethod |
+            CXCursor_ObjCInstanceMethodDecl => {
                 // For CXCursor_FunctionDecl, cursor.args() is the reliable way
                 // to get parameter names and types.
                 cursor.args()
                     .unwrap()
                     .iter()
                     .map(|arg| {
                         let arg_ty = arg.cur_type();
                         let name = arg.spelling();
@@ -213,35 +215,45 @@ impl FunctionSig {
             } else if is_virtual {
                 let void = Item::builtin_type(TypeKind::Void, false, ctx);
                 let ptr =
                     Item::builtin_type(TypeKind::Pointer(void), false, ctx);
                 args.insert(0, (Some("this".into()), ptr));
             }
         }
 
-        let ty_ret_type = try!(ty.ret_type().ok_or(ParseError::Continue));
+        let ty_ret_type = if cursor.kind() == CXCursor_ObjCInstanceMethodDecl {
+            try!(cursor.ret_type().ok_or(ParseError::Continue))
+        } else {
+            try!(ty.ret_type().ok_or(ParseError::Continue))
+        };
         let ret = Item::from_ty_or_ref(ty_ret_type, None, None, ctx);
         let abi = get_abi(ty.call_conv());
 
+        if abi.is_none() {
+            assert_eq!(cursor.kind(),
+                       CXCursor_ObjCInstanceMethodDecl,
+                       "Invalid ABI for function signature")
+        }
+
         Ok(Self::new(ret, args, ty.is_variadic(), abi))
     }
 
     /// Get this function signature's return type.
     pub fn return_type(&self) -> ItemId {
         self.return_type
     }
 
     /// Get this function signature's argument (name, type) pairs.
     pub fn argument_types(&self) -> &[(Option<String>, ItemId)] {
         &self.argument_types
     }
 
     /// Get this function signature's ABI.
-    pub fn abi(&self) -> abi::Abi {
+    pub fn abi(&self) -> Option<abi::Abi> {
         self.abi
     }
 
     /// Is this function signature variadic?
     pub fn is_variadic(&self) -> bool {
         // Clang reports some functions as variadic when they *might* be
         // variadic. We do the argument check because rust doesn't codegen well
         // variadic functions without an initial argument.
@@ -299,22 +311,21 @@ impl ClangSubItemParser for Function {
 
         let comment = cursor.raw_comment();
 
         let function = Self::new(name, mangled_name, sig, comment);
         Ok(ParseResult::New(function, Some(cursor)))
     }
 }
 
-impl TypeCollector for FunctionSig {
-    type Extra = Item;
+impl Trace for FunctionSig {
+    type Extra = ();
 
-    fn collect_types(&self,
-                     _context: &BindgenContext,
-                     types: &mut ItemSet,
-                     _item: &Item) {
-        types.insert(self.return_type());
+    fn trace<T>(&self, _: &BindgenContext, tracer: &mut T, _: &())
+        where T: Tracer,
+    {
+        tracer.visit(self.return_type());
 
         for &(_, ty) in self.argument_types() {
-            types.insert(ty);
+            tracer.visit(ty);
         }
     }
 }
--- a/third_party/rust/bindgen/src/ir/item.rs
+++ b/third_party/rust/bindgen/src/ir/item.rs
@@ -1,22 +1,23 @@
 //! Bindgen's core intermediate representation type.
 
 use super::annotations::Annotations;
-use super::context::{BindgenContext, ItemId};
-use super::derive::{CanDeriveCopy, CanDeriveDebug};
+use super::context::{BindgenContext, ItemId, PartialType};
+use super::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault};
 use super::function::Function;
 use super::item_kind::ItemKind;
 use super::module::Module;
-use super::ty::{Type, TypeKind};
-use super::type_collector::{ItemSet, TypeCollector};
+use super::traversal::{Trace, Tracer};
+use super::ty::{TemplateDeclaration, Type, TypeKind};
 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::iter;
 
 /// A trait to get the canonical name from an item.
 ///
 /// This is the trait that will eventually isolate all the logic related to name
 /// mangling and that kind of stuff.
 ///
@@ -161,61 +162,62 @@ impl ItemAncestors for ItemId {
 impl ItemAncestors for Item {
     fn ancestors<'a, 'b>(&self,
                          ctx: &'a BindgenContext<'b>)
                          -> ItemAncestorsIter<'a, 'b> {
         self.id().ancestors(ctx)
     }
 }
 
-impl TypeCollector for ItemId {
+impl Trace for ItemId {
     type Extra = ();
 
-    fn collect_types(&self,
-                     ctx: &BindgenContext,
-                     types: &mut ItemSet,
-                     extra: &()) {
-        ctx.resolve_item(*self).collect_types(ctx, types, extra);
+    fn trace<T>(&self, ctx: &BindgenContext, tracer: &mut T, extra: &())
+        where T: Tracer,
+    {
+        ctx.resolve_item(*self).trace(ctx, tracer, extra);
     }
 }
 
-impl TypeCollector for Item {
+impl Trace for Item {
     type Extra = ();
 
-    fn collect_types(&self,
-                     ctx: &BindgenContext,
-                     types: &mut ItemSet,
-                     _extra: &()) {
-        if self.is_hidden(ctx) || types.contains(&self.id()) {
+    fn trace<T>(&self, ctx: &BindgenContext, tracer: &mut T, _extra: &())
+        where T: Tracer,
+    {
+        if self.is_hidden(ctx) {
             return;
         }
 
         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) {
-                    ty.collect_types(ctx, types, self);
+                    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.
-                types.insert(fun.signature());
+                tracer.visit(fun.signature());
             }
             ItemKind::Var(ref var) => {
-                types.insert(var.ty());
+                tracer.visit(var.ty());
             }
             ItemKind::Module(_) => {
                 // Module -> children edges are "weak", and we do not want to
                 // trace them. If we did, then whitelisting wouldn't work as
                 // expected: everything in every module would end up
                 // whitelisted.
+                //
+                // TODO: make a new edge kind for module -> children edges and
+                // filter them during whitelisting traversals.
             }
         }
     }
 }
 
 impl CanDeriveDebug for Item {
     type Extra = ();
 
@@ -230,16 +232,36 @@ impl CanDeriveDebug for Item {
                     ty.can_derive_debug(ctx, ())
                 }
             }
             _ => false,
         }
     }
 }
 
+impl CanDeriveDefault 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) {
+                    ty.layout(ctx)
+                        .map_or(false,
+                                |l| l.opaque().can_derive_default(ctx, ()))
+                } else {
+                    ty.can_derive_default(ctx, ())
+                }
+            }
+            _ => false,
+        }
+    }
+}
+
 impl<'a> CanDeriveCopy<'a> for Item {
     type Extra = ();
 
     fn can_derive_copy(&self, ctx: &BindgenContext, _: ()) -> bool {
         match self.kind {
             ItemKind::Type(ref ty) => {
                 if self.is_opaque(ctx) {
                     ty.layout(ctx)
@@ -345,16 +367,30 @@ impl Item {
         }
     }
 
     /// Get this `Item`'s identifier.
     pub fn id(&self) -> ItemId {
         self.id
     }
 
+    /// Get this `Item`'s dot attributes.
+    pub fn dot_attributes(&self, ctx: &BindgenContext) -> String {
+        format!("[fontname=\"courier\", label=< \
+                 <table border=\"0\"> \
+                 <tr><td>ItemId({})</td></tr> \
+                 <tr><td>name</td><td>{}</td></tr> \
+                 <tr><td>kind</td><td>{}</td></tr> \
+                 </table> \
+                 >]",
+                self.id.as_usize(),
+                self.name(ctx).get(),
+                self.kind.kind_name())
+    }
+
     /// Get this `Item`'s parent's identifier.
     ///
     /// For the root module, the parent's ID is its own ID.
     pub fn parent_id(&self) -> ItemId {
         self.parent_id
     }
 
     /// Set this item's parent id.
@@ -445,16 +481,23 @@ impl Item {
     }
 
     /// Get a reference to this item's underlying `Type`, or `None` if this is
     /// some other kind of item.
     pub fn as_type(&self) -> Option<&Type> {
         self.kind().as_type()
     }
 
+    /// Is this item a named template type parameter?
+    pub fn is_named(&self) -> bool {
+        self.as_type()
+            .map(|ty| ty.is_named())
+            .unwrap_or(false)
+    }
+
     /// Get a reference to this item's underlying `Function`. Panic if this is
     /// some other kind of item.
     pub fn expect_function(&self) -> &Function {
         self.kind().expect_function()
     }
 
     /// Checks whether an item contains in its "type signature" some named type.
     ///
@@ -594,17 +637,17 @@ impl Item {
                         arg.is_named() &&
                         inner.signature_contains_named_type(ctx, arg)
                     })
                     .collect()
             }
             // XXX Is this completely correct? Partial template specialization
             // is hard anyways, sigh...
             TypeKind::TemplateAlias(_, ref args) |
-            TypeKind::TemplateRef(_, ref args) => args.clone(),
+            TypeKind::TemplateInstantiation(_, ref args) => args.clone(),
             // In a template specialization we've got all we want.
             TypeKind::Comp(ref ci) if ci.is_template_specialization() => {
                 ci.template_args().iter().cloned().collect()
             }
             TypeKind::Comp(ref ci) => {
                 let mut parent_template_args =
                     ctx.resolve_item(self.parent_id())
                         .applicable_template_args(ctx);
@@ -693,17 +736,17 @@ impl Item {
                         TypeKind::Comp(ref ci)
                             if ci.is_template_specialization() => {
                             let specialized =
                                 ci.specialized_template().unwrap();
                             item = ctx.resolve_item(specialized);
                         }
                         // Same as above.
                         TypeKind::ResolvedTypeRef(inner) |
-                        TypeKind::TemplateRef(inner, _) => {
+                        TypeKind::TemplateInstantiation(inner, _) => {
                             item = ctx.resolve_item(inner);
                         }
                         _ => return item.id(),
                     }
                 }
                 _ => return item.id(),
             }
         }
@@ -877,16 +920,46 @@ impl Item {
     pub fn as_module_mut(&mut self) -> Option<&mut Module> {
         match self.kind {
             ItemKind::Module(ref mut module) => Some(module),
             _ => None,
         }
     }
 }
 
+/// A set of items.
+pub type ItemSet = BTreeSet<ItemId>;
+
+impl TemplateDeclaration for ItemId {
+    fn template_params(&self, ctx: &BindgenContext) -> Option<Vec<ItemId>> {
+        ctx.resolve_item_fallible(*self)
+            .and_then(|item| item.template_params(ctx))
+    }
+}
+
+impl TemplateDeclaration for Item {
+    fn template_params(&self, ctx: &BindgenContext) -> Option<Vec<ItemId>> {
+        self.kind.template_params(ctx)
+    }
+}
+
+impl TemplateDeclaration for ItemKind {
+    fn template_params(&self, ctx: &BindgenContext) -> Option<Vec<ItemId>> {
+        match *self {
+            ItemKind::Type(ref ty) => ty.template_params(ctx),
+            // If we start emitting bindings to explicitly instantiated
+            // functions, then we'll need to check ItemKind::Function for
+            // template params.
+            ItemKind::Function(_) |
+            ItemKind::Module(_) |
+            ItemKind::Var(_) => None,
+        }
+    }
+}
+
 // An utility function to handle recursing inside nested types.
 fn visit_child(cur: clang::Cursor,
                id: ItemId,
                ty: &clang::Type,
                parent_id: Option<ItemId>,
                ctx: &mut BindgenContext,
                result: &mut Result<ItemId, ParseError>)
                -> clang_sys::CXChildVisitResult {
@@ -1151,28 +1224,28 @@ impl ClangItemParser for Item {
                                                 CXCursor_ClassTemplate {
             valid_decl = true;
             location.unwrap()
         } else {
             decl
         };
 
         if valid_decl {
-            if let Some(&(_, item_id)) =
-                ctx.currently_parsed_types
-                    .iter()
-                    .find(|&&(d, _)| d == declaration_to_look_for) {
+            if let Some(partial) = ctx.currently_parsed_types()
+                .iter()
+                .find(|ty| *ty.decl() == declaration_to_look_for) {
                 debug!("Avoiding recursion parsing type: {:?}", ty);
-                return Ok(item_id);
+                return Ok(partial.id());
             }
         }
 
         let current_module = ctx.current_module();
+        let partial_ty = PartialType::new(declaration_to_look_for, id);
         if valid_decl {
-            ctx.currently_parsed_types.push((declaration_to_look_for, id));
+            ctx.begin_parsing(partial_ty);
         }
 
         let result = Type::from_clang_ty(id, ty, location, parent_id, ctx);
         let relevant_parent_id = parent_id.unwrap_or(current_module);
         let ret = match result {
             Ok(ParseResult::AlreadyResolved(ty)) => Ok(ty),
             Ok(ParseResult::New(item, declaration)) => {
                 ctx.add_item(Item::new(id,
@@ -1190,28 +1263,28 @@ impl ClangItemParser for Item {
                 let mut result = Err(ParseError::Recurse);
                 if let Some(ref location) = location {
                     // Need to pop here, otherwise we'll get stuck.
                     //
                     // TODO: Find a nicer interface, really. Also, the
                     // declaration_to_look_for suspiciously shares a lot of
                     // logic with ir::context, so we should refactor that.
                     if valid_decl {
-                        let (popped_decl, _) =
-                            ctx.currently_parsed_types.pop().unwrap();
-                        assert_eq!(popped_decl, declaration_to_look_for);
+                        let finished = ctx.finish_parsing();
+                        assert_eq!(*finished.decl(), declaration_to_look_for);
                     }
 
                     location.visit(|cur| {
                         visit_child(cur, id, ty, parent_id, ctx, &mut result)
                     });
 
                     if valid_decl {
-                        ctx.currently_parsed_types
-                            .push((declaration_to_look_for, id));
+                        let partial_ty =
+                            PartialType::new(declaration_to_look_for, id);
+                        ctx.begin_parsing(partial_ty);
                     }
                 }
                 // If we have recursed into the AST all we know, and we still
                 // haven't found what we've got, let's just make a named type.
                 //
                 // This is what happens with some template members, for example.
                 //
                 // FIXME: Maybe we should restrict this to things with parent?
@@ -1228,18 +1301,18 @@ impl ClangItemParser for Item {
                                                 ctx))
                 } else {
                     result
                 }
             }
         };
 
         if valid_decl {
-            let (popped_decl, _) = ctx.currently_parsed_types.pop().unwrap();
-            assert_eq!(popped_decl, declaration_to_look_for);
+            let partial_ty = ctx.finish_parsing();
+            assert_eq!(*partial_ty.decl(), declaration_to_look_for);
         }
 
         ret
     }
 
     /// A named type is a template parameter, e.g., the "T" in Foo<T>. They're
     /// always local so it's the only exception when there's no declaration for
     /// a type.
--- a/third_party/rust/bindgen/src/ir/item_kind.rs
+++ b/third_party/rust/bindgen/src/ir/item_kind.rs
@@ -27,16 +27,26 @@ impl ItemKind {
     /// is some other kind.
     pub fn as_module(&self) -> Option<&Module> {
         match *self {
             ItemKind::Module(ref module) => Some(module),
             _ => None,
         }
     }
 
+    /// Transform our `ItemKind` into a string.
+    pub fn kind_name(&self) -> &'static str {
+        match *self {
+            ItemKind::Module(..) => "Module",
+            ItemKind::Type(..) => "Type",
+            ItemKind::Function(..) => "Function",
+            ItemKind::Var(..) => "Var"
+        }        
+    }
+
     /// Is this a module?
     pub fn is_module(&self) -> bool {
         self.as_module().is_some()
     }
 
     /// Get a reference to this `ItemKind`'s underying `Module`, or panic if it
     /// is some other kind.
     pub fn expect_module(&self) -> &Module {
--- a/third_party/rust/bindgen/src/ir/layout.rs
+++ b/third_party/rust/bindgen/src/ir/layout.rs
@@ -1,37 +1,58 @@
 //! Intermediate representation for the physical layout of some type.
 
 use super::context::BindgenContext;
-use super::derive::{CanDeriveCopy, CanDeriveDebug};
+use super::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault};
 use super::ty::RUST_DERIVE_IN_ARRAY_LIMIT;
-use std::cmp;
+use std::{cmp, mem};
 
 /// A type that represents the struct layout of a type.
-#[derive(Debug, Clone, Copy)]
+#[derive(Debug, Clone, Copy, PartialEq)]
 pub struct Layout {
     /// The size (in bytes) of this layout.
     pub size: usize,
     /// The alignment (in bytes) of this layout.
     pub align: usize,
     /// Whether this layout's members are packed or not.
     pub packed: bool,
 }
 
+#[test]
+fn test_layout_for_size() {
+    let ptr_size = mem::size_of::<*mut ()>();
+    assert_eq!(Layout::for_size(ptr_size), Layout::new(ptr_size, ptr_size));
+    assert_eq!(Layout::for_size(3 * ptr_size), Layout::new(3 * ptr_size, ptr_size));
+}
+
 impl Layout {
     /// Construct a new `Layout` with the given `size` and `align`. It is not
     /// packed.
     pub fn new(size: usize, align: usize) -> Self {
         Layout {
             size: size,
             align: align,
             packed: false,
         }
     }
 
+    /// Creates a non-packed layout for a given size, trying to use the maximum
+    /// alignment possible.
+    pub fn for_size(size: usize) -> Self {
+        let mut next_align = 2;
+        while size % next_align == 0 && next_align <= 2 * mem::size_of::<*mut ()>() {
+            next_align *= 2;
+        }
+        Layout {
+            size: size,
+            align: next_align / 2,
+            packed: false,
+        }
+    }
+
     /// Is this a zero-sized layout?
     pub fn is_zero(&self) -> bool {
         self.size == 0 && self.align == 0
     }
 
     /// Construct a zero-sized layout.
     pub fn zero() -> Self {
         Self::new(0, 0)
@@ -74,16 +95,25 @@ impl CanDeriveDebug for Opaque {
     type Extra = ();
 
     fn can_derive_debug(&self, _: &BindgenContext, _: ()) -> bool {
         self.array_size()
             .map_or(false, |size| size <= RUST_DERIVE_IN_ARRAY_LIMIT)
     }
 }
 
+impl CanDeriveDefault for Opaque {
+    type Extra = ();
+
+    fn can_derive_default(&self, _: &BindgenContext, _: ()) -> bool {
+        self.array_size()
+            .map_or(false, |size| size <= RUST_DERIVE_IN_ARRAY_LIMIT)
+    }
+}
+
 impl<'a> CanDeriveCopy<'a> for Opaque {
     type Extra = ();
 
     fn can_derive_copy(&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
@@ -9,12 +9,13 @@ pub mod context;
 pub mod derive;
 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 traversal;
 pub mod ty;
-pub mod type_collector;
 pub mod var;
 pub mod objc;
new file mode 100644
--- /dev/null
+++ b/third_party/rust/bindgen/src/ir/named.rs
@@ -0,0 +1,471 @@
+//! 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 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.
+//!
+//! 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 std::collections::HashMap;
+use std::fmt;
+use super::context::{BindgenContext, ItemId};
+use super::item::ItemSet;
+use super::traversal::{EdgeKind, Trace};
+use super::ty::{TemplateDeclaration, TypeKind};
+
+/// 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>;
+
+    /// 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.
+// TODO: This allow(...) is just temporary until we replace
+// `Item::signature_contains_named_type` with
+// `analyze::<UsedTemplateParameters>`.
+#[allow(dead_code)]
+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 the set of template parameters that actually end up
+/// used in our generated bindings.
+#[derive(Debug, Clone)]
+pub struct UsedTemplateParameters<'a> {
+    ctx: &'a BindgenContext<'a>,
+    used: ItemSet,
+    dependencies: HashMap<ItemId, Vec<ItemId>>,
+}
+
+impl<'a> MonotoneFramework for UsedTemplateParameters<'a> {
+    type Node = ItemId;
+    type Extra = &'a BindgenContext<'a>;
+    type Output = ItemSet;
+
+    fn new(ctx: &'a BindgenContext<'a>) -> UsedTemplateParameters<'a> {
+        let mut dependencies = HashMap::new();
+
+        for item in ctx.whitelisted_items() {
+            {
+                // We reverse our natural IR graph edges to find dependencies
+                // between nodes.
+                let mut add_reverse_edge = |sub_item, _| {
+                    dependencies.entry(sub_item).or_insert(vec![]).push(item);
+                };
+                item.trace(ctx, &mut add_reverse_edge, &());
+            }
+
+            // 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_fallible(item)
+                .and_then(|item| item.as_type())
+                .map(|ty| match ty.kind() {
+                    &TypeKind::TemplateInstantiation(decl, ref args) => {
+                        let decl = ctx.resolve_type(decl);
+                        let params = decl.template_params(ctx)
+                            .expect("a template instantiation's referenced \
+                                     template declaration should have template \
+                                     parameters");
+                        for (arg, param) in args.iter().zip(params.iter()) {
+                            dependencies.entry(*arg).or_insert(vec![]).push(*param);
+                        }
+                    }
+                    _ => {}
+                });
+        }
+
+        UsedTemplateParameters {
+            ctx: ctx,
+            used: ItemSet::new(),
+            dependencies: dependencies,
+        }
+    }
+
+    fn initial_worklist(&self) -> Vec<Self::Node> {
+        self.ctx.whitelisted_items().collect()
+    }
+
+    fn constrain(&mut self, item: ItemId) -> bool {
+        let original_size = self.used.len();
+
+        item.trace(self.ctx, &mut |item, edge_kind| {
+            if edge_kind == EdgeKind::TemplateParameterDefinition {
+                // The definition of a template parameter is not considered a
+                // use of said template parameter. Ignore this edge.
+                return;
+            }
+
+            let ty_kind = self.ctx.resolve_item(item)
+                .as_type()
+                .map(|ty| ty.kind());
+
+            match ty_kind {
+                Some(&TypeKind::Named) => {
+                    // This is a "trivial" use of the template type parameter.
+                    self.used.insert(item);
+                },
+                Some(&TypeKind::TemplateInstantiation(decl, ref args)) => {
+                    // A template instantiation's concrete template argument is
+                    // only used if the template declaration uses the
+                    // corresponding template parameter.
+                    let decl = self.ctx.resolve_type(decl);
+                    let params = decl.template_params(self.ctx)
+                        .expect("a template instantiation's referenced \
+                                 template declaration should have template \
+                                 parameters");
+                    for (arg, param) in args.iter().zip(params.iter()) {
+                        if self.used.contains(param) {
+                            if self.ctx.resolve_item(*arg).is_named() {
+                                self.used.insert(*arg);
+                            }
+                        }
+                    }
+                },
+                _ => return,
+            }
+        }, &());
+
+        let new_size = self.used.len();
+        new_size != original_size
+    }
+
+    fn each_depending_on<F>(&self, item: ItemId, mut f: F)
+        where F: FnMut(Self::Node)
+    {
+        if let Some(edges) = self.dependencies.get(&item) {
+            for item in edges {
+                f(*item);
+            }
+        }
+    }
+}
+
+impl<'a> From<UsedTemplateParameters<'a>> for ItemSet {
+    fn from(used_templ_params: UsedTemplateParameters) -> ItemSet {
+        used_templ_params.used
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::collections::{HashMap, HashSet};
+    use super::*;
+
+    // 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/objc.rs
+++ b/third_party/rust/bindgen/src/ir/objc.rs
@@ -1,13 +1,12 @@
 //! Objective C types
 
-// use clang_sys::CXCursor_ObjCSuperClassRef;
-
 use super::context::BindgenContext;
+use super::function::FunctionSig;
 use clang;
 use clang_sys::CXChildVisit_Continue;
 use clang_sys::CXCursor_ObjCInstanceMethodDecl;
 
 /// Objective C interface as used in TypeKind
 ///
 /// Also protocols are parsed as this type
 #[derive(Debug)]
@@ -25,16 +24,18 @@ pub struct ObjCInterface {
 pub struct ObjCInstanceMethod {
     /// The original method selector name
     /// like, dataWithBytes:length:
     name: String,
 
     /// Method name as converted to rust
     /// like, dataWithBytes_length_
     rust_name: String,
+
+    signature: FunctionSig,
 }
 
 impl ObjCInterface {
     fn new(name: &str) -> ObjCInterface {
         ObjCInterface {
             name: name.to_owned(),
             methods: Vec::new(),
         }
@@ -48,53 +49,86 @@ impl ObjCInterface {
 
     /// List of the methods defined in this interfae
     pub fn methods(&self) -> &Vec<ObjCInstanceMethod> {
         &self.methods
     }
 
     /// Parses the Objective C interface from the cursor
     pub fn from_ty(cursor: &clang::Cursor,
-                   _ctx: &mut BindgenContext)
+                   ctx: &mut BindgenContext)
                    -> Option<Self> {
         let name = cursor.spelling();
         let mut interface = Self::new(&name);
 
         cursor.visit(|cursor| {
             match cursor.kind() {
                 CXCursor_ObjCInstanceMethodDecl => {
                     let name = cursor.spelling();
-                    let method = ObjCInstanceMethod::new(&name);
+                    let signature =
+                        FunctionSig::from_ty(&cursor.cur_type(), &cursor, ctx)
+                            .expect("Invalid function sig");
+                    let method = ObjCInstanceMethod::new(&name, signature);
 
                     interface.methods.push(method);
                 }
                 _ => {}
             }
             CXChildVisit_Continue
         });
         Some(interface)
     }
 }
 
 impl ObjCInstanceMethod {
-    fn new(name: &str) -> ObjCInstanceMethod {
+    fn new(name: &str, signature: FunctionSig) -> ObjCInstanceMethod {
         let split_name: Vec<&str> = name.split(':').collect();
 
         let rust_name = split_name.join("_");
 
         ObjCInstanceMethod {
             name: name.to_owned(),
             rust_name: rust_name.to_owned(),
+            signature: signature,
         }
     }
 
     /// The original method selector name
     /// like, dataWithBytes:length:
     pub fn name(&self) -> &str {
         self.name.as_ref()
     }
 
     /// Method name as converted to rust
     /// like, dataWithBytes_length_
     pub fn rust_name(&self) -> &str {
         self.rust_name.as_ref()
     }
+
+    /// Returns the methods signature as FunctionSig
+    pub fn signature(&self) -> &FunctionSig {
+        &self.signature
+    }
+
+    /// Formats the method call
+    pub fn format_method_call(&self, args: &[String]) -> String {
+        let split_name: Vec<&str> =
+            self.name.split(':').filter(|p| !p.is_empty()).collect();
+
+        // No arguments
+        if args.len() == 0 && split_name.len() == 1 {
+            return split_name[0].to_string();
+        }
+
+        // Check right amount of arguments
+        if args.len() != split_name.len() {
+            panic!("Incorrect method name or arguments for objc method, {:?} vs {:?}",
+                   args,
+                   split_name);
+        }
+
+        split_name.iter()
+            .zip(args.iter())
+            .map(|parts| format!("{}:{} ", parts.0, parts.1))
+            .collect::<Vec<_>>()
+            .join("")
+    }
 }
new file mode 100644
--- /dev/null
+++ b/third_party/rust/bindgen/src/ir/traversal.rs
@@ -0,0 +1,360 @@
+//! Traversal of the graph of IR items and types.
+
+use super::context::{BindgenContext, ItemId};
+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
+/// yielded this outgoing edge.
+#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
+pub struct Edge {
+    to: ItemId,
+    kind: EdgeKind,
+}
+
+impl Edge {
+    /// Construct a new edge whose referent is `to` and is of the given `kind`.
+    pub fn new(to: ItemId, kind: EdgeKind) -> Edge {
+        Edge {
+            to: to,
+            kind: kind,
+        }
+    }
+
+    /// Get the item that this edge is pointing to.
+    pub fn to(&self) -> ItemId {
+        self.to
+    }
+
+    /// Get the kind of edge that this is.
+    pub fn kind(&self) -> EdgeKind {
+        self.kind
+    }
+}
+
+impl Into<ItemId> for Edge {
+    fn into(self) -> ItemId {
+        self.to
+    }
+}
+
+/// The kind of edge reference. This is useful when we wish to only consider
+/// certain kinds of edges for a particular traversal.
+#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
+pub enum EdgeKind {
+    /// A generic, catch-all edge.
+    Generic,
+
+    /// An edge from a template declaration, to the definition of a named type
+    /// parameter. For example, the edge Foo -> T in the following snippet:
+    ///
+    /// ```C++
+    /// template<typename T>
+    /// class Foo {
+    ///     int x;
+    /// };
+    /// ```
+    TemplateParameterDefinition,
+}
+
+/// 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;
+}
+
+impl TraversalPredicate for fn(Edge) -> bool {
+    fn should_follow(&self, edge: Edge) -> bool {
+        (*self)(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 {
+    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 {
+    false
+}
+
+/// 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
+    /// before, return `true`. Otherwise, return `false`.
+    ///
+    /// The `from` item is the item from which we discovered this item, or is
+    /// `None` if this item is a root.
+    fn add(&mut self, from: Option<ItemId>, item: ItemId) -> bool;
+}
+
+impl<'ctx, 'gen> TraversalStorage<'ctx, 'gen> for ItemSet {
+    fn new(_: &'ctx BindgenContext<'gen>) -> Self {
+        ItemSet::new()
+    }
+
+    fn add(&mut self, _: Option<ItemId>, item: ItemId) -> bool {
+        self.insert(item)
+    }
+}
+
+/// A `TraversalStorage` implementation that keeps track of how we first reached
+/// each item. This is useful for providing debug assertions with meaningful
+/// diagnostic messages about dangling items.
+#[derive(Debug)]
+pub struct Paths<'ctx, 'gen>(BTreeMap<ItemId, ItemId>,
+                             &'ctx BindgenContext<'gen>)
+    where 'gen: 'ctx;
+
+impl<'ctx, 'gen> TraversalStorage<'ctx, 'gen> for Paths<'ctx, 'gen>
+    where 'gen: 'ctx,
+{
+    fn new(ctx: &'ctx BindgenContext<'gen>) -> Self {
+        Paths(BTreeMap::new(), ctx)
+    }
+
+    fn add(&mut self, from: Option<ItemId>, item: ItemId) -> bool {
+        let newly_discovered =
+            self.0.insert(item, from.unwrap_or(item)).is_none();
+
+        if self.1.resolve_item_fallible(item).is_none() {
+            let mut path = vec![];
+            let mut current = item;
+            loop {
+                let predecessor = *self.0
+                    .get(&current)
+                    .expect("We know we found this item id, so it must have a \
+                            predecessor");
+                if predecessor == current {
+                    break;
+                }
+                path.push(predecessor);
+                current = predecessor;
+            }
+            path.reverse();
+            panic!("Found reference to dangling id = {:?}\nvia path = {:?}",
+                   item,
+                   path);
+        }
+
+        newly_discovered
+    }
+}
+
+/// The queue of seen-but-not-yet-traversed items.
+///
+/// Using a FIFO queue with a traversal will yield a breadth-first traversal,
+/// while using a LIFO queue will result in a depth-first traversal of the IR
+/// graph.
+pub trait TraversalQueue: Default {
+    /// Add a newly discovered item to the queue.
+    fn push(&mut self, item: ItemId);
+
+    /// Pop the next item to traverse, if any.
+    fn next(&mut self) -> Option<ItemId>;
+}
+
+impl TraversalQueue for Vec<ItemId> {
+    fn push(&mut self, item: ItemId) {
+        self.push(item);
+    }
+
+    fn next(&mut self) -> Option<ItemId> {
+        self.pop()
+    }
+}
+
+impl TraversalQueue for VecDeque<ItemId> {
+    fn push(&mut self, item: ItemId) {
+        self.push_back(item);
+    }
+
+    fn next(&mut self) -> Option<ItemId> {
+        self.pop_front()
+    }
+}
+
+/// Something that can receive edges from a `Trace` implementation.
+pub trait Tracer {
+    /// Note an edge between items. Called from within a `Trace` implementation.
+    fn visit_kind(&mut self, item: ItemId, kind: EdgeKind);
+
+    /// A synonym for `tracer.visit_kind(item, EdgeKind::Generic)`.
+    fn visit(&mut self, item: ItemId) {
+        self.visit_kind(item, EdgeKind::Generic);
+    }
+}
+
+impl<F> Tracer for F
+    where F: FnMut(ItemId, EdgeKind)
+{
+    fn visit_kind(&mut self, item: ItemId, kind: EdgeKind) {
+        (*self)(item, kind)
+    }
+}
+
+/// Trace all of the outgoing edges to other items. Implementations should call
+/// `tracer.visit(edge)` for each of their outgoing edges.
+pub trait Trace {
+    /// If a particular type needs extra information beyond what it has in
+    /// `self` and `context` to find its referenced items, its implementation
+    /// can define this associated type, forcing callers to pass the needed
+    /// information through.
+    type Extra;
+
+    /// Trace all of this item's outgoing edges to other items.
+    fn trace<T>(&self,
+                context: &BindgenContext,
+                tracer: &mut T,
+                extra: &Self::Extra)
+        where T: Tracer;
+}
+
+/// An graph traversal of the transitive closure of references between items.
+///
+/// See `BindgenContext::whitelisted_items` for more information.
+pub struct ItemTraversal<'ctx, 'gen, Storage, Queue, Predicate>
+    where 'gen: 'ctx,
+          Storage: TraversalStorage<'ctx, 'gen>,
+          Queue: TraversalQueue,
+          Predicate: TraversalPredicate,
+{
+    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.
+    predicate: Predicate,
+
+    /// The item we are currently traversing.
+    currently_traversing: Option<ItemId>,
+}
+
+impl<'ctx, 'gen, Storage, Queue, Predicate> ItemTraversal<'ctx,
+                                                          'gen,
+                                                          Storage,
+                                                          Queue,
+                                                          Predicate>
+    where 'gen: 'ctx,
+          Storage: TraversalStorage<'ctx, 'gen>,
+          Queue: TraversalQueue,
+          Predicate: TraversalPredicate,
+{
+    /// Begin a new traversal, starting from the given roots.
+    pub fn new<R>(ctx: &'ctx BindgenContext<'gen>,
+                  roots: R,
+                  predicate: Predicate)
+                  -> ItemTraversal<'ctx, 'gen, Storage, Queue, Predicate>
+        where R: IntoIterator<Item = ItemId>,
+    {
+        let mut seen = Storage::new(ctx);
+        let mut queue = Queue::default();
+
+        for id in roots {
+            seen.add(None, id);
+            queue.push(id);
+        }
+
+        ItemTraversal {
+            ctx: ctx,
+            seen: seen,
+            queue: queue,
+            predicate: predicate,
+            currently_traversing: None,
+        }
+    }
+}
+
+impl<'ctx, 'gen, Storage, Queue, Predicate> Tracer
+    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) {
+            return;
+        }
+
+        let is_newly_discovered = self.seen
+            .add(self.currently_traversing, item);
+        if is_newly_discovered {
+            self.queue.push(item)
+        }
+    }
+}
+
+impl<'ctx, 'gen, Storage, Queue, Predicate> Iterator
+    for ItemTraversal<'ctx, 'gen, Storage, Queue, Predicate>
+    where 'gen: 'ctx,
+          Storage: TraversalStorage<'ctx, 'gen>,
+          Queue: TraversalQueue,
+          Predicate: TraversalPredicate,
+{
+    type Item = ItemId;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        let id = match self.queue.next() {
+            None => return None,
+            Some(id) => id,
+        };
+
+        let newly_discovered = self.seen.add(None, id);
+        debug_assert!(!newly_discovered,
+                      "should have already seen anything we get out of our queue");
+        debug_assert!(self.ctx.resolve_item_fallible(id).is_some(),
+                      "should only get IDs of actual items in our context during traversal");
+
+        self.currently_traversing = Some(id);
+        id.trace(self.ctx, self, &());
+        self.currently_traversing = None;
+
+        Some(id)
+    }
+}
+
+/// An iterator to find any dangling items.
+///
+/// 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>;
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    #[allow(dead_code)]
+    fn traversal_predicate_is_object_safe() {
+        // This should compile only if TraversalPredicate is object safe.
+        fn takes_by_trait_object(_: &TraversalPredicate) {}
+    }
+}
--- a/third_party/rust/bindgen/src/ir/ty.rs
+++ b/third_party/rust/bindgen/src/ir/ty.rs
@@ -1,22 +1,46 @@
 //! Everything related to types in our intermediate representation.
 
 use super::comp::CompInfo;
 use super::context::{BindgenContext, ItemId};
-use super::derive::{CanDeriveCopy, CanDeriveDebug};
+use super::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault};
 use super::enum_ty::Enum;
 use super::function::FunctionSig;
 use super::int::IntKind;
 use super::item::Item;
 use super::layout::Layout;
 use super::objc::ObjCInterface;
-use super::type_collector::{ItemSet, TypeCollector};
+use super::traversal::{Trace, Tracer};
 use clang::{self, Cursor};
 use parse::{ClangItemParser, ParseError, ParseResult};
+use std::mem;
+
+/// Template declaration related methods.
+pub trait TemplateDeclaration {
+    /// Get the set of `ItemId`s that make up this template declaration's free
+    /// template parameters.
+    ///
+    /// Note that these might *not* all be named types: C++ allows
+    /// constant-value template parameters. Of course, Rust does not allow
+    /// generic parameters to be anything but types, so we must treat them as
+    /// opaque, and avoid instantiating them.
+    fn template_params(&self, ctx: &BindgenContext) -> Option<Vec<ItemId>>;
+
+    /// Get the number of free template parameters this template declaration
+    /// has.
+    ///
+    /// Implementations *may* return `Some` from this method when
+    /// `template_params` returns `None`. This is useful when we only have
+    /// partial information about the template declaration, such as when we are
+    /// in the middle of parsing it.
+    fn num_template_params(&self, ctx: &BindgenContext) -> Option<usize> {
+        self.template_params(ctx).map(|params| params.len())
+    }
+}
 
 /// 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.
 #[derive(Debug)]
 pub struct Type {
@@ -211,30 +235,30 @@ impl Type {
             }
         })
     }
 
     /// Whether this type has a vtable.
     pub fn has_vtable(&self, ctx: &BindgenContext) -> bool {
         // FIXME: Can we do something about template parameters? Huh...
         match self.kind {
-            TypeKind::TemplateRef(t, _) |
+            TypeKind::TemplateInstantiation(t, _) |
             TypeKind::TemplateAlias(t, _) |
             TypeKind::Alias(t) |
             TypeKind::ResolvedTypeRef(t) => ctx.resolve_type(t).has_vtable(ctx),
             TypeKind::Comp(ref info) => info.has_vtable(ctx),
             _ => false,
         }
 
     }
 
     /// Returns whether this type has a destructor.
     pub fn has_destructor(&self, ctx: &BindgenContext) -> bool {
         match self.kind {
-            TypeKind::TemplateRef(t, _) |
+            TypeKind::TemplateInstantiation(t, _) |
             TypeKind::TemplateAlias(t, _) |
             TypeKind::Alias(t) |
             TypeKind::ResolvedTypeRef(t) => {
                 ctx.resolve_type(t).has_destructor(ctx)
             }
             TypeKind::Comp(ref info) => info.has_destructor(ctx),
             _ => false,
         }
@@ -263,17 +287,17 @@ impl Type {
                 sig.argument_types().iter().any(|&(_, arg)| {
                     ctx.resolve_type(arg)
                         .signature_contains_named_type(ctx, ty)
                 }) ||
                 ctx.resolve_type(sig.return_type())
                     .signature_contains_named_type(ctx, ty)
             }
             TypeKind::TemplateAlias(_, ref template_args) |
-            TypeKind::TemplateRef(_, ref template_args) => {
+            TypeKind::TemplateInstantiation(_, ref template_args) => {
                 template_args.iter().any(|arg| {
                     ctx.resolve_type(*arg)
                         .signature_contains_named_type(ctx, ty)
                 })
             }
             TypeKind::Comp(ref ci) => ci.signature_contains_named_type(ctx, ty),
             _ => false,
         }
@@ -282,29 +306,31 @@ impl Type {
     /// Whether this named type is an invalid C++ identifier. This is done to
     /// avoid generating invalid code with some cases we can't handle, see:
     ///
     /// tests/headers/381-decltype-alias.hpp
     pub fn is_invalid_named_type(&self) -> bool {
         match self.kind {
             TypeKind::Named => {
                 let name = self.name().expect("Unnamed named type?");
-                let mut chars = name.chars();
-                let first = chars.next().unwrap();
-                let mut remaining = chars;
-
-                let valid = (first.is_alphabetic() || first == '_') &&
-                            remaining.all(|c| c.is_alphanumeric() || c == '_');
-
-                !valid
+                !Self::is_valid_identifier(&name)
             }
             _ => false,
         }
     }
 
+    /// Checks whether the name looks like an identifier,
+    /// i.e. is alphanumeric (including '_') and does not start with a digit.
+    pub fn is_valid_identifier(name: &str) -> bool {
+        let mut chars = name.chars();
+        let first_valid = chars.next().map(|c| c.is_alphabetic() || c == '_').unwrap_or(false);
+
+        first_valid && chars.all(|c| c.is_alphanumeric() || c == '_')
+    }
+
     /// See safe_canonical_type.
     pub fn canonical_type<'tr>(&'tr self,
                                ctx: &'tr BindgenContext)
                                -> &'tr Type {
         self.safe_canonical_type(ctx)
             .expect("Should have been resolved after parsing!")
     }
 
@@ -330,39 +356,119 @@ impl Type {
             TypeKind::NullPtr |
             TypeKind::BlockPointer |
             TypeKind::Pointer(..) |
             TypeKind::ObjCInterface(..) => Some(self),
 
             TypeKind::ResolvedTypeRef(inner) |
             TypeKind::Alias(inner) |
             TypeKind::TemplateAlias(inner, _) |
-            TypeKind::TemplateRef(inner, _) => {
+            TypeKind::TemplateInstantiation(inner, _) => {
                 ctx.resolve_type(inner).safe_canonical_type(ctx)
             }
 
             TypeKind::UnresolvedTypeRef(..) => None,
         }
     }
 
     /// There are some types we don't want to stop at when finding an opaque
     /// item, so we can arrive to the proper item that needs to be generated.
     pub fn should_be_traced_unconditionally(&self) -> bool {
         match self.kind {
             TypeKind::Function(..) |
             TypeKind::Pointer(..) |
             TypeKind::Array(..) |
             TypeKind::Reference(..) |
-            TypeKind::TemplateRef(..) |
+            TypeKind::TemplateInstantiation(..) |
             TypeKind::ResolvedTypeRef(..) => true,
             _ => false,
         }
     }
 }
 
+#[test]
+fn is_invalid_named_type_valid() {
+    let ty = Type::new(Some("foo".into()), None, TypeKind::Named, false);
+    assert!(!ty.is_invalid_named_type())
+}
+
+#[test]
+fn is_invalid_named_type_valid_underscore_and_numbers() {
+    let ty =
+        Type::new(Some("_foo123456789_".into()), None, TypeKind::Named, false);
+    assert!(!ty.is_invalid_named_type())
+}
+
+#[test]
+fn is_invalid_named_type_valid_unnamed_kind() {
+    let ty = Type::new(Some("foo".into()), None, TypeKind::Void, false);
+    assert!(!ty.is_invalid_named_type())
+}
+
+#[test]
+fn is_invalid_named_type_invalid_start() {
+    let ty = Type::new(Some("1foo".into()), None, TypeKind::Named, false);
+    assert!(ty.is_invalid_named_type())
+}
+
+#[test]
+fn is_invalid_named_type_invalid_remaing() {
+    let ty = Type::new(Some("foo-".into()), None, TypeKind::Named, false);
+    assert!(ty.is_invalid_named_type())
+}
+
+#[test]
+#[should_panic]
+fn is_invalid_named_type_unnamed() {
+    let ty = Type::new(None, None, TypeKind::Named, false);
+    assert!(ty.is_invalid_named_type())
+}
+
+#[test]
+fn is_invalid_named_type_empty_name() {
+    let ty = Type::new(Some("".into()), None, TypeKind::Named, false);
+    assert!(ty.is_invalid_named_type())
+}
+
+
+impl TemplateDeclaration for Type {
+    fn template_params(&self, ctx: &BindgenContext) -> Option<Vec<ItemId>> {
+        self.kind.template_params(ctx)
+    }
+}
+
+impl TemplateDeclaration for TypeKind {
+    fn template_params(&self, ctx: &BindgenContext) -> Option<Vec<ItemId>> {
+        match *self {
+            TypeKind::ResolvedTypeRef(id) => {
+                ctx.resolve_type(id).template_params(ctx)
+            }
+            TypeKind::Comp(ref comp) => comp.template_params(ctx),
+            TypeKind::TemplateAlias(_, ref args) => Some(args.clone()),
+
+            TypeKind::TemplateInstantiation(..) |
+            TypeKind::Void |
+            TypeKind::NullPtr |
+            TypeKind::Int(_) |
+            TypeKind::Float(_) |
+            TypeKind::Complex(_) |
+            TypeKind::Array(..) |
+            TypeKind::Function(_) |
+            TypeKind::Enum(_) |
+            TypeKind::Pointer(_) |
+            TypeKind::BlockPointer |
+            TypeKind::Reference(_) |
+            TypeKind::UnresolvedTypeRef(..) |
+            TypeKind::Named |
+            TypeKind::Alias(_) |
+            TypeKind::ObjCInterface(_) => None,
+        }
+    }
+}
+
 impl CanDeriveDebug for Type {
     type Extra = ();
 
     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, ())
             }
@@ -372,28 +478,61 @@ impl CanDeriveDebug for Type {
             TypeKind::Comp(ref info) => {
                 info.can_derive_debug(ctx, self.layout(ctx))
             }
             _ => true,
         }
     }
 }
 
+impl CanDeriveDefault for Type {
+    type Extra = ();
+
+    fn can_derive_default(&self, ctx: &BindgenContext, _: ()) -> 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))
+            }
+            TypeKind::Void |
+            TypeKind::Named |
+            TypeKind::TemplateInstantiation(..) |
+            TypeKind::Reference(..) |
+            TypeKind::NullPtr |
+            TypeKind::Pointer(..) |
+            TypeKind::BlockPointer |
+            TypeKind::ObjCInterface(..) |
+            TypeKind::Enum(..) => false,
+            TypeKind::Function(..) |
+            TypeKind::Int(..) |
+            TypeKind::Float(..) |
+            TypeKind::Complex(..) => true,
+            TypeKind::UnresolvedTypeRef(..) => unreachable!(),
+        }
+    }
+}
+
 impl<'a> CanDeriveCopy<'a> for Type {
     type Extra = &'a Item;
 
     fn can_derive_copy(&self, ctx: &BindgenContext, item: &Item) -> bool {
         match self.kind {
             TypeKind::Array(t, len) => {
                 len <= RUST_DERIVE_IN_ARRAY_LIMIT &&
                 t.can_derive_copy_in_array(ctx, ())
             }
             TypeKind::ResolvedTypeRef(t) |
             TypeKind::TemplateAlias(t, _) |
-            TypeKind::TemplateRef(t, _) |
+            TypeKind::TemplateInstantiation(t, _) |
             TypeKind::Alias(t) => t.can_derive_copy(ctx, ()),
             TypeKind::Comp(ref info) => {
                 info.can_derive_copy(ctx, (item, self.layout(ctx)))
             }
             _ => true,
         }
     }
 
@@ -420,16 +559,27 @@ pub enum FloatKind {
     /// A `double`.
     Double,
     /// A `long double`.
     LongDouble,
     /// A `__float128`.
     Float128,
 }
 
+impl FloatKind {
+    /// If this type has a known size, return it (in bytes).
+    pub fn known_size(&self) -> usize {
+        match *self {
+            FloatKind::Float => mem::size_of::<f32>(),
+            FloatKind::Double | FloatKind::LongDouble => mem::size_of::<f64>(),
+            FloatKind::Float128 => mem::size_of::<f64>() * 2,
+        }
+    }
+}
+
 /// The different kinds of types that we can parse.
 #[derive(Debug)]
 pub enum TypeKind {
     /// The void type.
     Void,
 
     /// The `nullptr_t` type.
     NullPtr,
@@ -468,20 +618,19 @@ pub enum TypeKind {
     Pointer(ItemId),
 
     /// A pointer to an Apple block.
     BlockPointer,
 
     /// A reference to a type, as in: int& foo().
     Reference(ItemId),
 
-    /// A reference to a template, with different template parameter names. To
-    /// see why this is needed, check out the creation of this variant in
-    /// `Type::from_clang_ty`.
-    TemplateRef(ItemId, Vec<ItemId>),
+    /// An instantiation of an abstract template declaration (first tuple
+    /// member) with a set of concrete template arguments (second tuple member).
+    TemplateInstantiation(ItemId, Vec<ItemId>),
 
     /// A reference to a yet-to-resolve type. This stores the clang cursor
     /// itself, and postpones its resolution.
     ///
     /// These are gone in a phase after parsing where these are mapped to
     /// already known types, and are converted to ResolvedTypeRef.
     ///
     /// see tests/headers/typeref.hpp to see somewhere where this is a problem.
@@ -515,17 +664,17 @@ impl Type {
             TypeKind::Void => true,
             TypeKind::Comp(ref ci) => ci.is_unsized(ctx),
             TypeKind::Array(inner, size) => {
                 size == 0 || ctx.resolve_type(inner).is_unsized(ctx)
             }
             TypeKind::ResolvedTypeRef(inner) |
             TypeKind::Alias(inner) |
             TypeKind::TemplateAlias(inner, _) |
-            TypeKind::TemplateRef(inner, _) => {
+            TypeKind::TemplateInstantiation(inner, _) => {
                 ctx.resolve_type(inner).is_unsized(ctx)
             }
             TypeKind::Named |
             TypeKind::Int(..) |
             TypeKind::Float(..) |
             TypeKind::Complex(..) |
             TypeKind::Function(..) |
             TypeKind::Enum(..) |
@@ -569,17 +718,17 @@ impl Type {
         let layout = ty.fallible_layout().ok();
         let cursor = ty.declaration();
         let mut name = cursor.spelling();
 
         debug!("from_clang_ty: {:?}, ty: {:?}, loc: {:?}",
                potential_id,
                ty,
                location);
-        debug!("currently_parsed_types: {:?}", ctx.currently_parsed_types);
+        debug!("currently_parsed_types: {:?}", ctx.currently_parsed_types());
 
         let canonical_ty = ty.canonical_type();
 
         // Parse objc protocols as if they were interfaces
         let mut ty_kind = ty.kind();
         if let Some(loc) = location {
             if loc.kind() == CXCursor_ObjCProtocolDecl {
                 ty_kind = CXType_ObjCInterface;
@@ -618,17 +767,19 @@ impl Type {
                     let signature = try!(FunctionSig::from_ty(ty,
                                                   &location.unwrap_or(cursor),
                                                   ctx));
                     TypeKind::Function(signature)
                     // Same here, with template specialisations we can safely
                     // assume this is a Comp(..)
                 } else if ty.is_fully_specialized_template() {
                     debug!("Template specialization: {:?}, {:?} {:?}",
-                           ty, location, canonical_ty);
+                           ty,
+                           location,
+                           canonical_ty);
                     let complex =
                         CompInfo::from_ty(potential_id, ty, location, ctx)
                             .expect("C'mon");
                     TypeKind::Comp(complex)
                 } else if let Some(location) = location {
                     match location.kind() {
                         CXCursor_ClassTemplatePartialSpecialization |
                         CXCursor_CXXBaseSpecifier |
@@ -839,82 +990,99 @@ impl Type {
             //
             // We might need to, though, if the context is already in the
             // process of resolving them.
             CXType_ObjCObjectPointer |
             CXType_MemberPointer |
             CXType_Pointer => {
                 let inner = Item::from_ty_or_ref(ty.pointee_type().unwrap(),
                                                  location,
-                                                 parent_id,
+                                                 None,
                                                  ctx);
                 TypeKind::Pointer(inner)
             }
             CXType_BlockPointer => TypeKind::BlockPointer,
             // XXX: RValueReference is most likely wrong, but I don't think we
             // can even add bindings for that, so huh.
             CXType_RValueReference |
             CXType_LValueReference => {
                 let inner = Item::from_ty_or_ref(ty.pointee_type().unwrap(),
                                                  location,
-                                                 parent_id,
+                                                 None,
                                                  ctx);
                 TypeKind::Reference(inner)
             }
             // XXX DependentSizedArray is wrong
             CXType_VariableArray |
             CXType_DependentSizedArray => {
                 let inner = Item::from_ty(ty.elem_type().as_ref().unwrap(),
                                           location,
-                                          parent_id,
+                                          None,
                                           ctx)
                     .expect("Not able to resolve array element?");
                 TypeKind::Pointer(inner)
             }
             CXType_IncompleteArray => {
                 let inner = Item::from_ty(ty.elem_type().as_ref().unwrap(),
                                           location,
-                                          parent_id,
+                                          None,
                                           ctx)
                     .expect("Not able to resolve array element?");
                 TypeKind::Array(inner, 0)
             }
             CXType_FunctionNoProto |
             CXType_FunctionProto => {
                 let signature = try!(FunctionSig::from_ty(ty,
                                               &location.unwrap_or(cursor),
                                               ctx));
                 TypeKind::Function(signature)
             }
             CXType_Typedef => {
                 let inner = cursor.typedef_type().expect("Not valid Type?");
-                let inner =
-                    Item::from_ty_or_ref(inner, location, parent_id, ctx);
+                let inner = Item::from_ty_or_ref(inner, location, None, ctx);
                 TypeKind::Alias(inner)
             }
             CXType_Enum => {
                 let enum_ = Enum::from_ty(ty, ctx).expect("Not an enum?");
+
+                if name.is_empty() {
+                    let pretty_name = ty.spelling();
+                    if Self::is_valid_identifier(&pretty_name) {
+                        name = pretty_name;
+                    }
+                }
+
                 TypeKind::Enum(enum_)
             }
             CXType_Record => {
                 let complex =
                     CompInfo::from_ty(potential_id, ty, location, ctx)
                         .expect("Not a complex type?");
+
+                if name.is_empty() {
+                    // The pretty-printed name may contain typedefed name,
+                    // but may also be "struct (anonymous at .h:1)"
+                    let pretty_name = ty.spelling();
+                    if Self::is_valid_identifier(&pretty_name) {
+                        name = pretty_name;
+                    }
+                }
+
                 TypeKind::Comp(complex)
             }
             // FIXME: We stub vectors as arrays since in 99% of the cases the
             // layout is going to be correct, and there's no way we can generate
             // vector types properly in Rust for now.
             //
             // That being said, that should be fixed eventually.
             CXType_Vector |
             CXType_ConstantArray => {
                 let inner = Item::from_ty(ty.elem_type().as_ref().unwrap(),
                                           location,
-                                          parent_id,
+                                          None,
                                           ctx)
                     .expect("Not able to resolve array element?");
                 TypeKind::Array(inner, ty.num_elements().unwrap())
             }
             CXType_Elaborated => {
                 return Self::from_clang_ty(potential_id,
                                            &ty.named(),
                                            location,
@@ -939,50 +1107,47 @@ impl Type {
         let is_const = ty.is_const();
 
         let ty = Type::new(name, layout, kind, is_const);
         // TODO: maybe declaration.canonical()?
         Ok(ParseResult::New(ty, Some(cursor.canonical())))
     }
 }
 
-impl TypeCollector for Type {
+impl Trace for Type {
     type Extra = Item;
 
-    fn collect_types(&self,
-                     context: &BindgenContext,
-                     types: &mut ItemSet,
-                     item: &Item) {
+    fn trace<T>(&self, context: &BindgenContext, tracer: &mut T, item: &Item)
+        where T: Tracer,
+    {
         match *self.kind() {
             TypeKind::Pointer(inner) |
             TypeKind::Reference(inner) |
             TypeKind::Array(inner, _) |
             TypeKind::Alias(inner) |
             TypeKind::ResolvedTypeRef(inner) => {
-                types.insert(inner);
+                tracer.visit(inner);
             }
 
             TypeKind::TemplateAlias(inner, ref template_args) |
-            TypeKind::TemplateRef(inner, ref template_args) => {
-                types.insert(inner);
+            TypeKind::TemplateInstantiation(inner, ref template_args) => {
+                tracer.visit(inner);
                 for &item in template_args {
-                    types.insert(item);
+                    tracer.visit(item);
                 }
             }
-            TypeKind::Comp(ref ci) => ci.collect_types(context, types, item),
-            TypeKind::Function(ref sig) => {
-                sig.collect_types(context, types, item)
-            }
+            TypeKind::Comp(ref ci) => ci.trace(context, tracer, item),
+            TypeKind::Function(ref sig) => sig.trace(context, tracer, &()),
             TypeKind::Enum(ref en) => {
                 if let Some(repr) = en.repr() {
-                    types.insert(repr);
+                    tracer.visit(repr);
                 }
             }
             TypeKind::UnresolvedTypeRef(_, _, Some(id)) => {
-                types.insert(id);
+                tracer.visit(id);
             }
 
             TypeKind::ObjCInterface(_) => {
                 // TODO:
             }
 
             // None of these variants have edges to other items and types.
             TypeKind::UnresolvedTypeRef(_, _, None) |
deleted file mode 100644
--- a/third_party/rust/bindgen/src/ir/type_collector.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-//! Collecting type items.
-
-use super::context::{BindgenContext, ItemId};
-use std::collections::BTreeSet;
-
-/// A set of items.
-pub type ItemSet = BTreeSet<ItemId>;
-
-/// Collect all the type items referenced by this item.
-pub trait TypeCollector {
-    /// If a particular type needs extra information beyond what it has in
-    /// `self` and `context` to find its referenced type items, its
-    /// implementation can define this associated type, forcing callers to pass
-    /// the needed information through.
-    type Extra;
-
-    /// Add each type item referenced by `self` into the `types` set.
-    fn collect_types(&self,
-                     context: &BindgenContext,
-                     types: &mut ItemSet,
-                     extra: &Self::Extra);
-}
--- a/third_party/rust/bindgen/src/lib.rs
+++ b/third_party/rust/bindgen/src/lib.rs
@@ -170,16 +170,23 @@ pub fn builder() -> Builder {
 impl Builder {
     /// Set the input C/C++ header.
     pub fn header<T: Into<String>>(mut self, header: T) -> Builder {
         let header = header.into();
         self.options.input_header = Some(header);
         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
+    }
+
     /// 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
@@ -315,16 +322,22 @@ impl Builder {
     }
 
     /// Set whether `Debug` should be derived by default.
     pub fn derive_debug(mut self, doit: bool) -> Self {
         self.options.derive_debug = doit;
         self
     }
 
+    /// Set whether `Default` should be derived by default.
+    pub fn derive_default(mut self, doit: bool) -> Self {
+        self.options.derive_default = doit;
+        self
+    }
+
     /// Emit Clang AST.
     pub fn emit_clang_ast(mut self) -> Builder {
         self.options.emit_ast = true;
         self
     }
 
     /// Emit IR.
     pub fn emit_ir(mut self) -> Builder {
@@ -480,27 +493,34 @@ pub struct BindgenOptions {
     pub links: Vec<(String, LinkType)>,
 
     /// True if we should dump the Clang AST for debugging purposes.
     pub emit_ast: bool,
 
     /// True if we should dump our internal IR for debugging purposes.
     pub emit_ir: bool,
 
+    /// Output graphviz dot file.
+    pub emit_ir_graphviz: Option<String>,
+
     /// True if we should emulate C++ namespaces with Rust modules in the
     /// generated bindings.
     pub enable_cxx_namespaces: bool,
 
     /// True if we should avoid mangling names with namespaces.
     pub disable_name_namespacing: bool,
 
     /// True if we shold derive Debug trait implementations for C/C++ structures
     /// and types.
     pub derive_debug: bool,
 
+    /// True if we shold derive Default trait implementations for C/C++ structures
+    /// and types.
+    pub derive_default: bool,
+
     /// True if we can use unstable Rust code in the bindings, false if we
     /// cannot.
     pub unstable_rust: bool,
 
     /// True if we should avoid using libstd to use libcore instead.
     pub use_core: bool,
 
     /// An optional prefix for the "raw" types, like `c_int`, `c_void`...
@@ -549,16 +569,21 @@ pub struct BindgenOptions {
     /// Wether to whitelist types recursively. Defaults to true.
     pub whitelist_recursively: bool,
 
     /// Intead of emitting 'use objc;' to files generated from objective c files,
     /// generate '#[macro_use] extern crate objc;'
     pub objc_extern_crate: 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
+/// it's ok.
+impl ::std::panic::UnwindSafe for BindgenOptions {}
+
 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();
@@ -575,17 +600,19 @@ impl Default for BindgenOptions {
             whitelisted_functions: Default::default(),
             whitelisted_vars: Default::default(),
             bitfield_enums: Default::default(),
             constified_enums: Default::default(),
             builtins: false,
             links: vec![],
             emit_ast: false,
             emit_ir: false,
+            emit_ir_graphviz: None,
             derive_debug: true,
+            derive_default: false,
             enable_cxx_namespaces: false,
             disable_name_namespacing: false,
             unstable_rust: true,
             use_core: false,
             ctypes_prefix: None,
             namespaced_constants: true,
             msvc_mangling: false,
             convert_floats: true,
--- a/third_party/rust/bindgen/src/main.rs
+++ b/third_party/rust/bindgen/src/main.rs
@@ -3,55 +3,77 @@ extern crate env_logger;
 #[macro_use]
 extern crate log;
 extern crate clang_sys;
 extern crate clap;
 extern crate rustc_serialize;
 
 use bindgen::clang_version;
 use std::env;
+use std::panic;
 
 mod options;
 use options::builder_from_flags;
 
 pub fn main() {
     log::set_logger(|max_log_level| {
             use env_logger::Logger;
             let env_logger = Logger::new();
             max_log_level.set(env_logger.filter());
             Box::new(env_logger)
         })
         .expect("Failed to set logger.");
 
     let bind_args: Vec<_> = env::args().collect();
 
     let version = clang_version();
-    let expected_version = if cfg!(feature = "llvm_stable") {
+    let expected_version = if cfg!(feature = "testing_only_llvm_stable") {
         (3, 8)
     } else {
         (3, 9)
     };
 
     info!("Clang Version: {}", version.full);
 
     match version.parsed {
         None => warn!("Couldn't parse libclang version"),
         Some(version) if version != expected_version => {
             warn!("Using clang {:?}, expected {:?}", version, expected_version);
         }
         _ => {}
     }
 
     match builder_from_flags(bind_args.into_iter()) {
-        Ok((builder, output)) => {
-            let mut bindings = builder.generate()
-                .expect("Unable to generate bindings");
+        Ok((builder, output, verbose)) => {
+
+            let builder_result = panic::catch_unwind(|| {
+                builder.generate().expect("Unable to generate bindings")
+            });
+
+            if builder_result.is_err() {
+                if verbose {
+                    print_verbose_err();
+                }
+                std::process::exit(1);
+            }
+
+            let mut bindings = builder_result.unwrap();
             bindings.write(output)
                 .expect("Unable to write output");
             bindings.write_dummy_uses()
                 .expect("Unable to write dummy uses to file.");
         }
         Err(error) => {
             println!("{}", error);
             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), \
+              please modify the bindgen flags to work around it as \
+              described in https://github.com/servo/rust-bindgen#c");
+    println!("Otherwise, please file an issue at \
+              https://github.com/servo/rust-bindgen/issues/new");
+}
--- a/third_party/rust/bindgen/src/options.rs
+++ b/third_party/rust/bindgen/src/options.rs
@@ -1,16 +1,17 @@
 use bindgen::{Builder, CodegenConfig, builder};
 use clap::{App, Arg};
 use std::fs::File;
 use std::io::{self, Error, ErrorKind};
 
 /// Construct a new [`Builder`](./struct.Builder.html) from command line flags.
-pub fn builder_from_flags<I>(args: I)
-                             -> Result<(Builder, Box<io::Write>), io::Error>
+pub fn builder_from_flags<I>
+    (args: I)
+     -> Result<(Builder, Box<io::Write>, bool), io::Error>
     where I: Iterator<Item = String>,
 {
     let matches = App::new("bindgen")
         .version(env!("CARGO_PKG_VERSION"))
         .about("Generates Rust bindings from C/C++ headers.")
         .usage("bindgen [FLAGS] [OPTIONS] <header> -- <clang-args>...")
         .args(&[
             Arg::with_name("header")
@@ -37,16 +38,23 @@ pub fn builder_from_flags<I>(args: I)
                 .help("Mark a type as hidden.")
                 .value_name("type")
                 .takes_value(true)
                 .multiple(true)
                 .number_of_values(1),
             Arg::with_name("no-derive-debug")
                 .long("no-derive-debug")
                 .help("Avoid deriving Debug on any type."),
+            Arg::with_name("no-derive-default")
+                .long("no-derive-default")
+                .hidden(true)
+                .help("Avoid deriving Default on any type."),
+            Arg::with_name("with-derive-default")
+                .long("with-derive-default")
+                .help("Deriving 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"),
             Arg::with_name("no-recursive-whitelist")
                 .long("no-recursive-whitelist")
                 .help("Avoid whitelisting types recursively"),
             Arg::with_name("objc-extern-crate")
@@ -71,16 +79,21 @@ pub fn builder_from_flags<I>(args: I)
                        dummy uses of all types defined in the input header.")
                 .takes_value(true),
             Arg::with_name("emit-clang-ast")
                 .long("emit-clang-ast")
                 .help("Output the Clang AST for debugging purposes."),
             Arg::with_name("emit-ir")
                 .long("emit-ir")
                 .help("Output our internal IR for debugging purposes."),
+            Arg::with_name("emit-ir-graphviz")
+                .long("emit-ir-graphviz")
+                .help("Dump graphviz dot file.")
+                .value_name("path")
+                .takes_value(true),
             Arg::with_name("enable-cxx-namespaces")
                 .long("enable-cxx-namespaces")
                 .help("Enable support for C++ namespaces."),
             Arg::with_name("disable-name-namespacing")
                 .long("disable-name-namespacing")
                 .help("Disable name namespacing if namespaces are disabled."),
             Arg::with_name("framework")
                 .long("framework-link")
@@ -170,16 +183,19 @@ pub fn builder_from_flags<I>(args: I)
                 .long("whitelist-var")
                 .help("Whitelist all the free-standing variables matching \
                        <regex>. Other non-whitelisted variables will not be \
                        generated.")
                 .value_name("regex")
                 .takes_value(true)
                 .multiple(true)
                 .number_of_values(1),
+            Arg::with_name("verbose")
+                .long("verbose")
+                .help("Print verbose error messages"),
         ]) // .args()
         .get_matches_from(args);
 
     let mut builder = builder();
 
     if let Some(header) = matches.value_of("header") {
         builder = builder.header(header);
     } else {
@@ -207,16 +223,24 @@ pub fn builder_from_flags<I>(args: I)
     if matches.is_present("builtins") {
         builder = builder.emit_builtins();
     }
 
     if matches.is_present("no-derive-debug") {
         builder = builder.derive_debug(false);
     }
 
+    if matches.is_present("with-derive-default") {
+        builder = builder.derive_default(true);
+    }
+
+    if matches.is_present("no-derive-default") {
+        builder = builder.derive_default(false);
+    }
+
     if let Some(prefix) = matches.value_of("ctypes-prefix") {
         builder = builder.ctypes_prefix(prefix);
     }
 
     if let Some(dummy) = matches.value_of("dummy-uses") {
         builder = builder.dummy_uses(dummy);
     }
 
@@ -246,16 +270,20 @@ pub fn builder_from_flags<I>(args: I)
     if matches.is_present("emit-clang-ast") {
         builder = builder.emit_clang_ast();
     }
 
     if matches.is_present("emit-ir") {
         builder = builder.emit_ir();
     }
 
+    if let Some(path) = matches.value_of("emit-ir-graphviz") {
+        builder = builder.emit_ir_graphviz(path);
+    }
+
     if matches.is_present("enable-cxx-namespaces") {
         builder = builder.enable_cxx_namespaces();
     }
 
     if matches.is_present("disable-name-namespacing") {
         builder = builder.disable_name_namespacing();
     }
 
@@ -341,10 +369,12 @@ pub fn builder_from_flags<I>(args: 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>
     };
 
-    Ok((builder, output))
+    let verbose = matches.is_present("verbose");
+
+    Ok((builder, output, verbose))
 }
new file mode 100644
--- /dev/null
+++ b/third_party/rust/bindgen/tests/headers/bitfield_align.h
@@ -0,0 +1,41 @@
+struct A {
+  unsigned char x;
+  unsigned b1 : 1;
+  unsigned b2 : 1;
+  unsigned b3 : 1;
+  unsigned b4 : 1;
+  unsigned b5 : 1;
+  unsigned b6 : 1;
+  unsigned b7 : 1;
+  unsigned b8 : 1;
+  unsigned b9 : 1;
+  unsigned b10 : 1;
+  unsigned char y;
+};
+
+struct B {
+  unsigned foo : 31;
+  unsigned char bar : 1;
+};
+
+struct C {
+  unsigned char x;
+  unsigned b1 : 1;
+  unsigned b2 : 1;
+  unsigned baz;
+};
+
+struct Date1 {
+   unsigned short nWeekDay  : 3;    // 0..7   (3 bits)
+   unsigned short nMonthDay : 6;    // 0..31  (6 bits)
+   unsigned short nMonth    : 5;    // 0..12  (5 bits)
+   unsigned short nYear     : 8;    // 0..100 (8 bits)
+};
+
+struct Date2 {
+   unsigned short nWeekDay  : 3;    // 0..7   (3 bits)
+   unsigned short nMonthDay : 6;    // 0..31  (6 bits)
+   unsigned short nMonth    : 5;    // 0..12  (5 bits)
+   unsigned short nYear     : 8;    // 0..100 (8 bits)
+   unsigned char byte;
+};
--- a/third_party/rust/bindgen/tests/headers/class_nested.hpp
+++ b/third_party/rust/bindgen/tests/headers/class_nested.hpp
@@ -1,17 +1,29 @@
 class A {
 public:
     int member_a;
     class B {
         int member_b;
     };
+
+    class C;
+
+    template<typename T>
+    class D {
+      T foo;
+    };
+};
+
+class A::C {
+  int baz;
 };
 
 A::B var;
+A::D<int> baz;
 
 class D {
     A::B member;
 };
 
 template<typename T>
 class Templated {
     T member;
new file mode 100644
--- /dev/null
+++ b/third_party/rust/bindgen/tests/headers/const_array_fn_arg.h
@@ -0,0 +1,1 @@
+void f(const int a[]);
new file mode 100644
--- /dev/null
+++ b/third_party/rust/bindgen/tests/headers/issue-446.hpp
@@ -0,0 +1,11 @@
+// bindgen-flags: -- -std=c++14
+
+template <typename Elem>
+class List {
+    List<Elem> *next;
+};
+
+template <typename GcThing>
+class PersistentRooted {
+    List<PersistentRooted<GcThing>> root_list;
+};
new file mode 100644
--- /dev/null
+++ b/third_party/rust/bindgen/tests/headers/issue-493.hpp
@@ -0,0 +1,47 @@
+template<class _CharT, class _Traits, class _Allocator>
+class basic_string
+{
+public:
+    typedef unsigned long long size_type;
+    typedef char value_type;
+    typedef value_type * pointer;
+
+    struct __long
+    {
+        size_type __cap_;
+        size_type __size_;
+        pointer   __data_;
+    };
+
+    enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ?
+                        (sizeof(__long) - 1)/sizeof(value_type) : 2};
+
+    struct __short
+    {
+        union
+        {
+            unsigned char __size_;
+            value_type __lx;
+        };
+        value_type __data_[__min_cap];
+    };
+
+    union __ulx{__long __lx; __short __lxx;};
+
+    enum {__n_words = sizeof(__ulx) / sizeof(size_type)};
+
+    struct __raw
+    {
+        size_type __words[__n_words];
+    };
+
+    struct __rep
+    {
+        union
+        {
+            __long  __l;
+            __short __s;
+            __raw   __r;
+        };
+    };
+};
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/third_party/rust/bindgen/tests/headers/layout.h
@@ -0,0 +1,6 @@
+struct header
+{
+    char proto;
+    unsigned int size __attribute__ ((packed));
+    unsigned char data[] __attribute__ ((aligned(8)));
+} __attribute__ ((aligned, packed));
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/third_party/rust/bindgen/tests/headers/layout_align.h
@@ -0,0 +1,20 @@
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long uint64_t;
+
+struct rte_kni_fifo {
+	volatile unsigned write;     /**< Next position to be written*/
+	volatile unsigned read;      /**< Next position to be read */
+	unsigned len;                /**< Circular buffer length */
+	unsigned elem_size;          /**< Pointer size - for 32/64 bit OS */
+	void *volatile buffer[];     /**< The buffer contains mbuf pointers */
+};
+
+__extension__
+struct rte_eth_link {
+	uint32_t link_speed;        /**< ETH_SPEED_NUM_ */
+	uint16_t link_duplex  : 1;  /**< ETH_LINK_[HALF/FULL]_DUPLEX */
+	uint16_t link_autoneg : 1;  /**< ETH_LINK_SPEED_[AUTONEG/FIXED] */
+	uint16_t link_status  : 1;  /**< ETH_LINK_[DOWN/UP] */
+} __attribute__((aligned(8)));      /**< aligned for atomic64 read/write */
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/third_party/rust/bindgen/tests/headers/layout_arp.h
@@ -0,0 +1,52 @@
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long uint64_t;
+
+#define ETHER_ADDR_LEN  6 /**< Length of Ethernet address. */
+
+/**
+ * Ethernet address:
+ * A universally administered address is uniquely assigned to a device by its
+ * manufacturer. The first three octets (in transmission order) contain the
+ * Organizationally Unique Identifier (OUI). The following three (MAC-48 and
+ * EUI-48) octets are assigned by that organization with the only constraint
+ * of uniqueness.
+ * A locally administered address is assigned to a device by a network
+ * administrator and does not contain OUIs.
+ * See http://standards.ieee.org/regauth/groupmac/tutorial.html
+ */
+struct ether_addr {
+	uint8_t addr_bytes[ETHER_ADDR_LEN]; /**< Addr bytes in tx order */
+} __attribute__((__packed__));
+
+/**
+ * ARP header IPv4 payload.
+ */
+struct arp_ipv4 {
+	struct ether_addr arp_sha;  /**< sender hardware address */
+	uint32_t          arp_sip;  /**< sender IP address */
+	struct ether_addr arp_tha;  /**< target hardware address */
+	uint32_t          arp_tip;  /**< target IP address */
+} __attribute__((__packed__));
+
+/**
+ * ARP header.
+ */
+struct arp_hdr {
+	uint16_t arp_hrd;    /* format of hardware address */
+#define ARP_HRD_ETHER     1  /* ARP Ethernet address format */
+
+	uint16_t arp_pro;    /* format of protocol address */
+	uint8_t  arp_hln;    /* length of hardware address */
+	uint8_t  arp_pln;    /* length of protocol address */
+	uint16_t arp_op;     /* ARP opcode (command) */
+#define	ARP_OP_REQUEST    1 /* request to resolve address */
+#define	ARP_OP_REPLY      2 /* response to previous request */
+#define	ARP_OP_REVREQUEST 3 /* request proto addr given hardware */
+#define	ARP_OP_REVREPLY   4 /* response giving protocol address */
+#define	ARP_OP_INVREQUEST 8 /* request to identify peer */
+#define	ARP_OP_INVREPLY   9 /* response identifying peer */
+
+	struct arp_ipv4 arp_data;
+} __attribute__((__packed__));
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/third_party/rust/bindgen/tests/headers/layout_array.h
@@ -0,0 +1,109 @@
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long uint64_t;
+
+typedef long long size_t;
+
+#define RTE_CACHE_LINE_SIZE 64
+
+/**
+ * Force alignment
+ */
+#define __rte_aligned(a) __attribute__((__aligned__(a)))
+
+/**
+ * Force alignment to cache line.
+ */
+#define __rte_cache_aligned __rte_aligned(RTE_CACHE_LINE_SIZE)
+
+#define RTE_MEMPOOL_OPS_NAMESIZE 32 /**< Max length of ops struct name. */
+
+/**
+ * Prototype for implementation specific data provisioning function.
+ *
+ * The function should provide the implementation specific memory for
+ * for use by the other mempool ops functions in a given mempool ops struct.
+ * E.g. the default ops provides an instance of the rte_ring for this purpose.
+ * it will most likely point to a different type of data structure, and
+ * will be transparent to the application programmer.
+ * This function should set mp->pool_data.
+ */
+typedef int (*rte_mempool_alloc_t)(struct rte_mempool *mp);
+
+/**
+ * Free the opaque private data pointed to by mp->pool_data pointer.
+ */
+typedef void (*rte_mempool_free_t)(struct rte_mempool *mp);
+
+/**
+ * Enqueue an object into the external pool.
+ */
+typedef int (*rte_mempool_enqueue_t)(struct rte_mempool *mp,
+		void * const *obj_table, unsigned int n);
+
+/**
+ * Dequeue an object from the external pool.
+ */
+typedef int (*rte_mempool_dequeue_t)(struct rte_mempool *mp,
+		void **obj_table, unsigned int n);
+
+/**
+ * Return the number of available objects in the external pool.
+ */
+typedef unsigned (*rte_mempool_get_count)(const struct rte_mempool *mp);
+/** Structure defining mempool operations structure */
+struct rte_mempool_ops {
+	char name[RTE_MEMPOOL_OPS_NAMESIZE]; /**< Name of mempool ops struct. */
+	rte_mempool_alloc_t alloc;       /**< Allocate private data. */
+	rte_mempool_free_t free;         /**< Free the external pool. */
+	rte_mempool_enqueue_t enqueue;   /**< Enqueue an object. */
+	rte_mempool_dequeue_t dequeue;   /**< Dequeue an object. */
+	rte_mempool_get_count get_count; /**< Get qty of available objs. */
+} __rte_cache_aligned;
+
+#define RTE_MEMPOOL_MAX_OPS_IDX 16  /**< Max registered ops structs */
+
+/**
+ * The rte_spinlock_t type.
+ */
+typedef struct {
+	volatile int locked; /**< lock status 0 = unlocked, 1 = locked */
+} rte_spinlock_t;
+
+/**
+ * Structure storing the table of registered ops structs, each of which contain
+ * the function pointers for the mempool ops functions.
+ * Each process has its own storage for this ops struct array so that
+ * the mempools can be shared across primary and secondary processes.
+ * The indices used to access the array are valid across processes, whereas
+ * any function pointers stored directly in the mempool struct would not be.
+ * This results in us simply having "ops_index" in the mempool struct.
+ */
+struct rte_mempool_ops_table {
+	rte_spinlock_t sl;     /**< Spinlock for add/delete. */
+	uint32_t num_ops;      /**< Number of used ops structs in the table. */
+	/**
+	 * Storage for all possible ops structs.
+	 */
+	struct rte_mempool_ops ops[RTE_MEMPOOL_MAX_OPS_IDX];
+} __rte_cache_aligned;
+
+
+/* Number of free lists per heap, grouped by size. */
+#define RTE_HEAP_NUM_FREELISTS  13
+
+#define LIST_HEAD(name, type)                                           \
+struct name {                                                           \
+		struct type *lh_first;  /* first element */                     \
+}
+
+/**
+ * Structure to hold malloc heap
+ */
+struct malloc_heap {
+	rte_spinlock_t lock;
+	LIST_HEAD(, malloc_elem) free_head[RTE_HEAP_NUM_FREELISTS];
+	unsigned alloc_count;
+	size_t total_size;
+} __rte_cache_aligned;
new file mode 100644
--- /dev/null
+++ b/third_party/rust/bindgen/tests/headers/layout_cmdline_token.h
@@ -0,0 +1,63 @@
+
+/**
+ * Stores a pointer to the ops struct, and the offset: the place to
+ * write the parsed result in the destination structure.
+ */
+struct cmdline_token_hdr {
+	struct cmdline_token_ops *ops;
+	unsigned int offset;
+};
+typedef struct cmdline_token_hdr cmdline_parse_token_hdr_t;
+
+/**
+ * A token is defined by this structure.
+ *
+ * parse() takes the token as first argument, then the source buffer
+ * starting at the token we want to parse. The 3rd arg is a pointer
+ * where we store the parsed data (as binary). It returns the number of
+ * parsed chars on success and a negative value on error.
+ *
+ * complete_get_nb() returns the number of possible values for this
+ * token if completion is possible. If it is NULL or if it returns 0,
+ * no completion is possible.
+ *
+ * complete_get_elt() copy in dstbuf (the size is specified in the
+ * parameter) the i-th possible completion for this token.  returns 0
+ * on success or and a negative value on error.
+ *
+ * get_help() fills the dstbuf with the help for the token. It returns
+ * -1 on error and 0 on success.
+ */
+struct cmdline_token_ops {
+	/** parse(token ptr, buf, res pts, buf len) */
+	int (*parse)(cmdline_parse_token_hdr_t *, const char *, void *,
+		unsigned int);
+	/** return the num of possible choices for this token */
+	int (*complete_get_nb)(cmdline_parse_token_hdr_t *);
+	/** return the elt x for this token (token, idx, dstbuf, size) */
+	int (*complete_get_elt)(cmdline_parse_token_hdr_t *, int, char *,
+		unsigned int);
+	/** get help for this token (token, dstbuf, size) */
+	int (*get_help)(cmdline_parse_token_hdr_t *, char *, unsigned int);
+};
+
+enum cmdline_numtype {
+	UINT8 = 0,
+	UINT16,
+	UINT32,
+	UINT64,
+	INT8,
+	INT16,
+	INT32,
+	INT64
+};
+
+struct cmdline_token_num_data {
+	enum cmdline_numtype type;
+};
+
+struct cmdline_token_num {
+	struct cmdline_token_hdr hdr;
+	struct cmdline_token_num_data num_data;
+};
+typedef struct cmdline_token_num cmdline_parse_token_num_t;
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/third_party/rust/bindgen/tests/headers/layout_eth_conf.h
@@ -0,0 +1,427 @@
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long uint64_t;
+
+/**
+ *  Simple flags are used for rte_eth_conf.rxmode.mq_mode.
+ */
+#define ETH_MQ_RX_RSS_FLAG  0x1
+#define ETH_MQ_RX_DCB_FLAG  0x2
+#define ETH_MQ_RX_VMDQ_FLAG 0x4
+
+/* Definitions used for VMDQ and DCB functionality */
+#define ETH_VMDQ_MAX_VLAN_FILTERS   64 /**< Maximum nb. of VMDQ vlan filters. */
+#define ETH_DCB_NUM_USER_PRIORITIES 8  /**< Maximum nb. of DCB priorities. */
+#define ETH_VMDQ_DCB_NUM_QUEUES     128 /**< Maximum nb. of VMDQ DCB queues. */
+#define ETH_DCB_NUM_QUEUES          128 /**< Maximum nb. of DCB queues. */
+
+/**
+ *  A set of values to identify what method is to be used to route
+ *  packets to multiple queues.
+ */
+enum rte_eth_rx_mq_mode {
+	/** None of DCB,RSS or VMDQ mode */
+	ETH_MQ_RX_NONE = 0,
+
+	/** For RX side, only RSS is on */
+	ETH_MQ_RX_RSS = ETH_MQ_RX_RSS_FLAG,
+	/** For RX side,only DCB is on. */
+	ETH_MQ_RX_DCB = ETH_MQ_RX_DCB_FLAG,
+	/** Both DCB and RSS enable */
+	ETH_MQ_RX_DCB_RSS = ETH_MQ_RX_RSS_FLAG | ETH_MQ_RX_DCB_FLAG,
+
+	/** Only VMDQ, no RSS nor DCB */
+	ETH_MQ_RX_VMDQ_ONLY = ETH_MQ_RX_VMDQ_FLAG,
+	/** RSS mode with VMDQ */
+	ETH_MQ_RX_VMDQ_RSS = ETH_MQ_RX_RSS_FLAG | ETH_MQ_RX_VMDQ_FLAG,
+	/** Use VMDQ+DCB to route traffic to queues */
+	ETH_MQ_RX_VMDQ_DCB = ETH_MQ_RX_VMDQ_FLAG | ETH_MQ_RX_DCB_FLAG,
+	/** Enable both VMDQ and DCB in VMDq */
+	ETH_MQ_RX_VMDQ_DCB_RSS = ETH_MQ_RX_RSS_FLAG | ETH_MQ_RX_DCB_FLAG |
+				 ETH_MQ_RX_VMDQ_FLAG,
+};
+
+/**
+ * A structure used to configure the RX features of an Ethernet port.
+ */
+struct rte_eth_rxmode {
+	/** The multi-queue packet distribution mode to be used, e.g. RSS. */
+	enum rte_eth_rx_mq_mode mq_mode;
+	uint32_t max_rx_pkt_len;  /**< Only used if jumbo_frame enabled. */
+	uint16_t split_hdr_size;  /**< hdr buf size (header_split enabled).*/
+	__extension__
+	uint16_t header_split : 1, /**< Header Split enable. */
+		hw_ip_checksum   : 1, /**< IP/UDP/TCP checksum offload enable. */
+		hw_vlan_filter   : 1, /**< VLAN filter enable. */
+		hw_vlan_strip    : 1, /**< VLAN strip enable. */
+		hw_vlan_extend   : 1, /**< Extended VLAN enable. */
+		jumbo_frame      : 1, /**< Jumbo Frame Receipt enable. */
+		hw_strip_crc     : 1, /**< Enable CRC stripping by hardware. */
+		enable_scatter   : 1, /**< Enable scatter packets rx handler */
+		enable_lro       : 1; /**< Enable LRO */
+};
+
+/**
+ * A set of values to identify what method is to be used to transmit
+ * packets using multi-TCs.
+ */
+enum rte_eth_tx_mq_mode {
+	ETH_MQ_TX_NONE    = 0,  /**< It is in neither DCB nor VT mode. */
+	ETH_MQ_TX_DCB,          /**< For TX side,only DCB is on. */
+	ETH_MQ_TX_VMDQ_DCB,	/**< For TX side,both DCB and VT is on. */
+	ETH_MQ_TX_VMDQ_ONLY,    /**< Only VT on, no DCB */
+};
+
+/**
+ * A structure used to configure the TX features of an Ethernet port.
+ */
+struct rte_eth_txmode {
+	enum rte_eth_tx_mq_mode mq_mode; /**< TX multi-queues mode. */
+
+	/* For i40e specifically */
+	uint16_t pvid;
+	__extension__
+	uint8_t hw_vlan_reject_tagged : 1,
+		/**< If set, reject sending out tagged pkts */
+		hw_vlan_reject_untagged : 1,
+		/**< If set, reject sending out untagged pkts */
+		hw_vlan_insert_pvid : 1;
+		/**< If set, enable port based VLAN insertion */
+};
+
+/**
+ * A structure used to configure the Receive Side Scaling (RSS) feature
+ * of an Ethernet port.
+ * If not NULL, the *rss_key* pointer of the *rss_conf* structure points
+ * to an array holding the RSS key to use for hashing specific header
+ * fields of received packets. The length of this array should be indicated
+ * by *rss_key_len* below. Otherwise, a default random hash key is used by
+ * the device driver.
+ *
+ * The *rss_key_len* field of the *rss_conf* structure indicates the length
+ * in bytes of the array pointed by *rss_key*. To be compatible, this length
+ * will be checked in i40e only. Others assume 40 bytes to be used as before.
+ *
+ * The *rss_hf* field of the *rss_conf* structure indicates the different
+ * types of IPv4/IPv6 packets to which the RSS hashing must be applied.
+ * Supplying an *rss_hf* equal to zero disables the RSS feature.
+ */
+struct rte_eth_rss_conf {
+	uint8_t *rss_key;    /**< If not NULL, 40-byte hash key. */
+	uint8_t rss_key_len; /**< hash key length in bytes. */
+	uint64_t rss_hf;     /**< Hash functions to apply - see below. */
+};
+
+/**
+ * This enum indicates the possible number of traffic classes
+ * in DCB configratioins
+ */
+enum rte_eth_nb_tcs {
+	ETH_4_TCS = 4, /**< 4 TCs with DCB. */
+	ETH_8_TCS = 8  /**< 8 TCs with DCB. */
+};
+
+/**
+ * This enum indicates the possible number of queue pools
+ * in VMDQ configurations.
+ */
+enum rte_eth_nb_pools {
+	ETH_8_POOLS = 8,    /**< 8 VMDq pools. */
+	ETH_16_POOLS = 16,  /**< 16 VMDq pools. */
+	ETH_32_POOLS = 32,  /**< 32 VMDq pools. */
+	ETH_64_POOLS = 64   /**< 64 VMDq pools. */
+};
+
+/**
+ * A structure used to configure the VMDQ+DCB feature
+ * of an Ethernet port.
+ *
+ * Using this feature, packets are routed to a pool of queues, based
+ * on the vlan id in the vlan tag, and then to a specific queue within
+ * that pool, using the user priority vlan tag field.
+ *
+ * A default pool may be used, if desired, to route all traffic which
+ * does not match the vlan filter rules.
+ */
+struct rte_eth_vmdq_dcb_conf {
+	enum rte_eth_nb_pools nb_queue_pools; /**< With DCB, 16 or 32 pools */
+	uint8_t enable_default_pool; /**< If non-zero, use a default pool */
+	uint8_t default_pool; /**< The default pool, if applicable */
+	uint8_t nb_pool_maps; /**< We can have up to 64 filters/mappings */
+	struct {
+		uint16_t vlan_id; /**< The vlan id of the received frame */
+		uint64_t pools;   /**< Bitmask of pools for packet rx */
+	} pool_map[ETH_VMDQ_MAX_VLAN_FILTERS]; /**< VMDq vlan pool maps. */
+	uint8_t dcb_tc[ETH_DCB_NUM_USER_PRIORITIES];
+	/**< Selects a queue in a pool */
+};
+
+/* This structure may be extended in future. */
+struct rte_eth_dcb_rx_conf {
+	enum rte_eth_nb_tcs nb_tcs; /**< Possible DCB TCs, 4 or 8 TCs */
+	/** Traffic class each UP mapped to. */
+	uint8_t dcb_tc[ETH_DCB_NUM_USER_PRIORITIES];
+};
+
+struct rte_eth_vmdq_dcb_tx_conf {
+	enum rte_eth_nb_pools nb_queue_pools; /**< With DCB, 16 or 32 pools. */
+	/** Traffic class each UP mapped to. */
+	uint8_t dcb_tc[ETH_DCB_NUM_USER_PRIORITIES];
+};
+
+struct rte_eth_dcb_tx_conf {
+	enum rte_eth_nb_tcs nb_tcs; /**< Possible DCB TCs, 4 or 8 TCs. */
+	/** Traffic class each UP mapped to. */
+	uint8_t dcb_tc[ETH_DCB_NUM_USER_PRIORITIES];
+};
+
+struct rte_eth_vmdq_tx_conf {
+	enum rte_eth_nb_pools nb_queue_pools; /**< VMDq mode, 64 pools. */
+};
+
+struct rte_eth_vmdq_rx_conf {
+	enum rte_eth_nb_pools nb_queue_pools; /**< VMDq only mode, 8 or 64 pools */
+	uint8_t enable_default_pool; /**< If non-zero, use a default pool */
+	uint8_t default_pool; /**< The default pool, if applicable */
+	uint8_t enable_loop_back; /**< Enable VT loop back */
+	uint8_t nb_pool_maps; /**< We can have up to 64 filters/mappings */
+	uint32_t rx_mode; /**< Flags from ETH_VMDQ_ACCEPT_* */
+	struct {
+		uint16_t vlan_id; /**< The vlan id of the received frame */
+		uint64_t pools;   /**< Bitmask of pools for packet rx */
+	} pool_map[ETH_VMDQ_MAX_VLAN_FILTERS]; /**< VMDq vlan pool maps. */
+};
+
+/**
+ *  Flow Director setting modes: none, signature or perfect.
+ */
+enum rte_fdir_mode {
+	RTE_FDIR_MODE_NONE      = 0, /**< Disable FDIR support. */
+	RTE_FDIR_MODE_SIGNATURE,     /**< Enable FDIR signature filter mode. */
+	RTE_FDIR_MODE_PERFECT,       /**< Enable FDIR perfect filter mode. */
+	RTE_FDIR_MODE_PERFECT_MAC_VLAN, /**< Enable FDIR filter mode - MAC VLAN. */
+	RTE_FDIR_MODE_PERFECT_TUNNEL,   /**< Enable FDIR filter mode - tunnel. */
+};
+
+/**
+ *  Memory space that can be configured to store Flow Director filters
+ *  in the board memory.
+ */
+enum rte_fdir_pballoc_type {
+	RTE_FDIR_PBALLOC_64K = 0,  /**< 64k. */
+	RTE_FDIR_PBALLOC_128K,     /**< 128k. */
+	RTE_FDIR_PBALLOC_256K,     /**< 256k. */
+};
+
+/**
+ *  Select report mode of FDIR hash information in RX descriptors.
+ */
+enum rte_fdir_status_mode {
+	RTE_FDIR_NO_REPORT_STATUS = 0, /**< Never report FDIR hash. */
+	RTE_FDIR_REPORT_STATUS, /**< Only report FDIR hash for matching pkts. */
+	RTE_FDIR_REPORT_STATUS_ALWAYS, /**< Always report FDIR hash. */
+};
+
+/**
+ * A structure used to define the input for IPV4 flow
+ */
+struct rte_eth_ipv4_flow {
+	uint32_t src_ip;      /**< IPv4 source address in big endian. */
+	uint32_t dst_ip;      /**< IPv4 destination address in big endian. */
+	uint8_t  tos;         /**< Type of service to match. */
+	uint8_t  ttl;         /**< Time to live to match. */
+	uint8_t  proto;       /**< Protocol, next header in big endian. */
+};
+
+/**
+ * A structure used to define the input for IPV6 flow
+ */
+struct rte_eth_ipv6_flow {
+	uint32_t src_ip[4];      /**< IPv6 source address in big endian. */
+	uint32_t dst_ip[4];      /**< IPv6 destination address in big endian. */
+	uint8_t  tc;             /**< Traffic class to match. */
+	uint8_t  proto;          /**< Protocol, next header to match. */
+	uint8_t  hop_limits;     /**< Hop limits to match. */
+};
+
+/**
+ *  A structure used to configure FDIR masks that are used by the device
+ *  to match the various fields of RX packet headers.
+ */
+struct rte_eth_fdir_masks {
+	uint16_t vlan_tci_mask;   /**< Bit mask for vlan_tci in big endian */
+	/** Bit mask for ipv4 flow in big endian. */
+	struct rte_eth_ipv4_flow   ipv4_mask;
+	/** Bit maks for ipv6 flow in big endian. */
+	struct rte_eth_ipv6_flow   ipv6_mask;
+	/** Bit mask for L4 source port in big endian. */
+	uint16_t src_port_mask;
+	/** Bit mask for L4 destination port in big endian. */
+	uint16_t dst_port_mask;
+	/** 6 bit mask for proper 6 bytes of Mac address, bit 0 matches the
+	    first byte on the wire */
+	uint8_t mac_addr_byte_mask;
+	/** Bit mask for tunnel ID in big endian. */
+	uint32_t tunnel_id_mask;
+	uint8_t tunnel_type_mask; /**< 1 - Match tunnel type,
+				       0 - Ignore tunnel type. */
+};
+
+/**
+ * Payload type
+ */
+enum rte_eth_payload_type {
+	RTE_ETH_PAYLOAD_UNKNOWN = 0,
+	RTE_ETH_RAW_PAYLOAD,
+	RTE_ETH_L2_PAYLOAD,
+	RTE_ETH_L3_PAYLOAD,
+	RTE_ETH_L4_PAYLOAD,
+	RTE_ETH_PAYLOAD_MAX = 8,
+};
+
+#define RTE_ETH_FDIR_MAX_FLEXLEN 16  /**< Max length of flexbytes. */
+#define RTE_ETH_INSET_SIZE_MAX   128 /**< Max length of input set. */
+
+/**
+ * A structure used to select bytes extracted from the protocol layers to
+ * flexible payload for filter
+ */
+struct rte_eth_flex_payload_cfg {
+	enum rte_eth_payload_type type;  /**< Payload type */
+	uint16_t src_offset[RTE_ETH_FDIR_MAX_FLEXLEN];
+	/**< Offset in bytes from the beginning of packet's payload
+	     src_offset[i] indicates the flexbyte i's offset in original
+	     packet payload. This value should be less than
+	     flex_payload_limit in struct rte_eth_fdir_info.*/
+};
+
+/**
+ * A structure used to define FDIR masks for flexible payload
+ * for each flow type
+ */
+struct rte_eth_fdir_flex_mask {
+	uint16_t flow_type;
+	uint8_t mask[RTE_ETH_FDIR_MAX_FLEXLEN];
+	/**< Mask for the whole flexible payload */
+};
+
+
+/*
+ * A packet can be identified by hardware as different flow types. Different
+ * NIC hardwares may support different flow types.
+ * Basically, the NIC hardware identifies the flow type as deep protocol as
+ * possible, and exclusively. For example, if a packet is identified as
+ * 'RTE_ETH_FLOW_NONFRAG_IPV4_TCP', it will not be any of other flow types,
+ * though it is an actual IPV4 packet.
+ * Note that the flow types are used to define RSS offload types in
+ * rte_ethdev.h.
+ */
+#define RTE_ETH_FLOW_UNKNOWN             0
+#define RTE_ETH_FLOW_RAW                 1
+#define RTE_ETH_FLOW_IPV4                2
+#define RTE_ETH_FLOW_FRAG_IPV4           3
+#define RTE_ETH_FLOW_NONFRAG_IPV4_TCP    4
+#define RTE_ETH_FLOW_NONFRAG_IPV4_UDP    5
+#define RTE_ETH_FLOW_NONFRAG_IPV4_SCTP   6
+#define RTE_ETH_FLOW_NONFRAG_IPV4_OTHER  7
+#define RTE_ETH_FLOW_IPV6                8
+#define RTE_ETH_FLOW_FRAG_IPV6           9
+#define RTE_ETH_FLOW_NONFRAG_IPV6_TCP   10
+#define RTE_ETH_FLOW_NONFRAG_IPV6_UDP   11
+#define RTE_ETH_FLOW_NONFRAG_IPV6_SCTP  12
+#define RTE_ETH_FLOW_NONFRAG_IPV6_OTHER 13
+#define RTE_ETH_FLOW_L2_PAYLOAD         14
+#define RTE_ETH_FLOW_IPV6_EX            15
+#define RTE_ETH_FLOW_IPV6_TCP_EX        16
+#define RTE_ETH_FLOW_IPV6_UDP_EX        17
+#define RTE_ETH_FLOW_PORT               18
+	/**< Consider device port number as a flow differentiator */
+#define RTE_ETH_FLOW_VXLAN              19 /**< VXLAN protocol based flow */
+#define RTE_ETH_FLOW_GENEVE             20 /**< GENEVE protocol based flow */
+#define RTE_ETH_FLOW_NVGRE              21 /**< NVGRE protocol based flow */
+#define RTE_ETH_FLOW_MAX                22
+
+/**
+ * A structure used to define all flexible payload related setting
+ * include flex payload and flex mask
+ */
+struct rte_eth_fdir_flex_conf {
+	uint16_t nb_payloads;  /**< The number of following payload cfg */
+	uint16_t nb_flexmasks; /**< The number of following mask */
+	struct rte_eth_flex_payload_cfg flex_set[RTE_ETH_PAYLOAD_MAX];
+	/**< Flex payload configuration for each payload type */
+	struct rte_eth_fdir_flex_mask flex_mask[RTE_ETH_FLOW_MAX];
+	/**< Flex mask configuration for each flow type */
+};
+
+/**
+ * A structure used to configure the Flow Director (FDIR) feature
+ * of an Ethernet port.
+ *
+ * If mode is RTE_FDIR_DISABLE, the pballoc value is ignored.
+ */
+struct rte_fdir_conf {
+	enum rte_fdir_mode mode; /**< Flow Director mode. */
+	enum rte_fdir_pballoc_type pballoc; /**< Space for FDIR filters. */
+	enum rte_fdir_status_mode status;  /**< How to report FDIR hash. */
+	/** RX queue of packets matching a "drop" filter in perfect mode. */
+	uint8_t drop_queue;
+	struct rte_eth_fdir_masks mask;
+	struct rte_eth_fdir_flex_conf flex_conf;
+	/**< Flex payload configuration. */
+};
+
+/**
+ * A structure used to enable/disable specific device interrupts.
+ */
+struct rte_intr_conf {
+	/** enable/disable lsc interrupt. 0 (default) - disable, 1 enable */
+	uint16_t lsc;
+	/** enable/disable rxq interrupt. 0 (default) - disable, 1 enable */
+	uint16_t rxq;
+};
+
+/**
+ * A structure used to configure an Ethernet port.
+ * Depending upon the RX multi-queue mode, extra advanced
+ * configuration settings may be needed.
+ */
+struct rte_eth_conf {
+	uint32_t link_speeds; /**< bitmap of ETH_LINK_SPEED_XXX of speeds to be
+				used. ETH_LINK_SPEED_FIXED disables link
+				autonegotiation, and a unique speed shall be
+				set. Otherwise, the bitmap defines the set of
+				speeds to be advertised. If the special value
+				ETH_LINK_SPEED_AUTONEG (0) is used, all speeds
+				supported are advertised. */
+	struct rte_eth_rxmode rxmode; /**< Port RX configuration. */
+	struct rte_eth_txmode txmode; /**< Port TX configuration. */
+	uint32_t lpbk_mode; /**< Loopback operation mode. By default the value
+			         is 0, meaning the loopback mode is disabled.
+				 Read the datasheet of given ethernet controller
+				 for details. The possible values of this field
+				 are defined in implementation of each driver. */
+	struct {
+		struct rte_eth_rss_conf rss_conf; /**< Port RSS configuration */
+		struct rte_eth_vmdq_dcb_conf vmdq_dcb_conf;
+		/**< Port vmdq+dcb configuration. */
+		struct rte_eth_dcb_rx_conf dcb_rx_conf;
+		/**< Port dcb RX configuration. */
+		struct rte_eth_vmdq_rx_conf vmdq_rx_conf;
+		/**< Port vmdq RX configuration. */
+	} rx_adv_conf; /**< Port RX filtering configuration (union). */
+	union {
+		struct rte_eth_vmdq_dcb_tx_conf vmdq_dcb_tx_conf;
+		/**< Port vmdq+dcb TX configuration. */
+		struct rte_eth_dcb_tx_conf dcb_tx_conf;
+		/**< Port dcb TX configuration. */
+		struct rte_eth_vmdq_tx_conf vmdq_tx_conf;
+		/**< Port vmdq TX configuration. */
+	} tx_adv_conf; /**< Port TX DCB configuration (union). */
+	/** Currently,Priority Flow Control(PFC) are supported,if DCB with PFC
+	    is needed,and the variable must be set ETH_DCB_PFC_SUPPORT. */
+	uint32_t dcb_capability_en;
+	struct rte_fdir_conf fdir_conf; /**< FDIR configuration. */
+	struct rte_intr_conf intr_conf; /**< Interrupt mode configuration. */
+};
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/third_party/rust/bindgen/tests/headers/layout_kni_mbuf.h
@@ -0,0 +1,32 @@
+
+#define RTE_CACHE_LINE_MIN_SIZE 64	/**< Minimum Cache line size. */
+
+#define RTE_CACHE_LINE_SIZE 64
+
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long uint64_t;
+
+/*
+ * The kernel image of the rte_mbuf struct, with only the relevant fields.
+ * Padding is necessary to assure the offsets of these fields
+ */
+struct rte_kni_mbuf {
+	void *buf_addr __attribute__((__aligned__(RTE_CACHE_LINE_SIZE)));
+	uint64_t buf_physaddr;
+	char pad0[2];
+	uint16_t data_off;      /**< Start address of data in segment buffer. */
+	char pad1[2];
+	uint8_t nb_segs;        /**< Number of segments. */
+	char pad4[1];
+	uint64_t ol_flags;      /**< Offload features. */
+	char pad2[4];
+	uint32_t pkt_len;       /**< Total pkt len: sum of all segment data_len. */
+	uint16_t data_len;      /**< Amount of data in segment buffer. */
+
+	/* fields on second cache line */
+	char pad3[8] __attribute__((__aligned__(RTE_CACHE_LINE_MIN_SIZE)));
+	void *pool;
+	void *next;
+};
new file mode 100644
--- /dev/null
+++ b/third_party/rust/bindgen/tests/headers/layout_mbuf.h
@@ -0,0 +1,187 @@
+
+#define RTE_CACHE_LINE_MIN_SIZE 64	/**< Minimum Cache line size. */
+
+#define RTE_CACHE_LINE_SIZE 64
+
+typedef char int8_t;
+typedef short int16_t;
+typedef int int32_t;
+typedef long long int64_t;
+
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long uint64_t;
+
+typedef uint64_t phys_addr_t;
+
+/**
+ * Force alignment
+ */
+#define __rte_aligned(a) __attribute__((__aligned__(a)))
+
+/**
+ * Force alignment to cache line.
+ */
+#define __rte_cache_aligned __rte_aligned(RTE_CACHE_LINE_SIZE)
+
+/**
+ * Force minimum cache line alignment.
+ */
+#define __rte_cache_min_aligned __rte_aligned(RTE_CACHE_LINE_MIN_SIZE)
+
+/* define a set of marker types that can be used to refer to set points in the
+ * mbuf */
+__extension__
+typedef void    *MARKER[0];   /**< generic marker for a point in a structure */
+__extension__
+typedef uint8_t  MARKER8[0];  /**< generic marker with 1B alignment */
+__extension__
+typedef uint64_t MARKER64[0]; /**< marker that allows us to overwrite 8 bytes
+                               * with a single assignment */
+
+/** C extension macro for environments lacking C11 features. */
+#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112L
+#define RTE_STD_C11 __extension__
+#else
+#define RTE_STD_C11
+#endif
+
+/**
+ * The atomic counter structure.
+ */
+typedef struct {
+	volatile int16_t cnt; /**< An internal counter value. */
+} rte_atomic16_t;
+
+/**
+ * The generic rte_mbuf, containing a packet mbuf.
+ */
+struct rte_mbuf {
+	MARKER cacheline0;
+
+	void *buf_addr;           /**< Virtual address of segment buffer. */
+	phys_addr_t buf_physaddr; /**< Physical address of segment buffer. */
+
+	uint16_t buf_len;         /**< Length of segment buffer. */
+
+	/* next 6 bytes are initialised on RX descriptor rearm */
+	MARKER8 rearm_data;
+	uint16_t data_off;
+
+	/**
+	 * 16-bit Reference counter.
+	 * It should only be accessed using the following functions:
+	 * rte_mbuf_refcnt_update(), rte_mbuf_refcnt_read(), and
+	 * rte_mbuf_refcnt_set(). The functionality of these functions (atomic,
+	 * or non-atomic) is controlled by the CONFIG_RTE_MBUF_REFCNT_ATOMIC
+	 * config option.
+	 */
+	RTE_STD_C11
+	union {
+		rte_atomic16_t refcnt_atomic; /**< Atomically accessed refcnt */
+		uint16_t refcnt;              /**< Non-atomically accessed refcnt */
+	};
+	uint8_t nb_segs;          /**< Number of segments. */
+	uint8_t port;             /**< Input port. */
+
+	uint64_t ol_flags;        /**< Offload features. */
+
+	/* remaining bytes are set on RX when pulling packet from descriptor */
+	MARKER rx_descriptor_fields1;
+
+	/*
+	 * The packet type, which is the combination of outer/inner L2, L3, L4
+	 * and tunnel types. The packet_type is about data really present in the
+	 * mbuf. Example: if vlan stripping is enabled, a received vlan packet
+	 * would have RTE_PTYPE_L2_ETHER and not RTE_PTYPE_L2_VLAN because the
+	 * vlan is stripped from the data.
+	 */
+	RTE_STD_C11
+	union {
+		uint32_t packet_type; /**< L2/L3/L4 and tunnel information. */
+		struct {
+			uint32_t l2_type:4; /**< (Outer) L2 type. */
+			uint32_t l3_type:4; /**< (Outer) L3 type. */
+			uint32_t l4_type:4; /**< (Outer) L4 type. */
+			uint32_t tun_type:4; /**< Tunnel type. */
+			uint32_t inner_l2_type:4; /**< Inner L2 type. */
+			uint32_t inner_l3_type:4; /**< Inner L3 type. */
+			uint32_t inner_l4_type:4; /**< Inner L4 type. */
+		};
+	};
+
+	uint32_t pkt_len;         /**< Total pkt len: sum of all segments. */
+	uint16_t data_len;        /**< Amount of data in segment buffer. */
+	/** VLAN TCI (CPU order), valid if PKT_RX_VLAN_STRIPPED is set. */
+	uint16_t vlan_tci;
+
+	union {
+		uint32_t rss;     /**< RSS hash result if RSS enabled */
+		struct {
+			RTE_STD_C11
+			union {
+				struct {
+					uint16_t hash;
+					uint16_t id;
+				};
+				uint32_t lo;
+				/**< Second 4 flexible bytes */
+			};
+			uint32_t hi;
+			/**< First 4 flexible bytes or FD ID, dependent on
+			     PKT_RX_FDIR_* flag in ol_flags. */
+		} fdir;           /**< Filter identifier if FDIR enabled */
+		struct {
+			uint32_t lo;
+			uint32_t hi;
+		} sched;          /**< Hierarchical scheduler */
+		uint32_t usr;	  /**< User defined tags. See rte_distributor_process() */
+	} hash;                   /**< hash information */
+
+	uint32_t seqn; /**< Sequence number. See also rte_reorder_insert() */
+
+	/** Outer VLAN TCI (CPU order), valid if PKT_RX_QINQ_STRIPPED is set. */
+	uint16_t vlan_tci_outer;
+
+	/* second cache line - fields only used in slow path or on TX */
+	MARKER cacheline1 __rte_cache_min_aligned;
+
+	RTE_STD_C11
+	union {
+		void *userdata;   /**< Can be used for external metadata */
+		uint64_t udata64; /**< Allow 8-byte userdata on 32-bit */
+	};
+
+	struct rte_mempool *pool; /**< Pool from which mbuf was allocated. */
+	struct rte_mbuf *next;    /**< Next segment of scattered packet. */
+
+	/* fields to support TX offloads */
+	RTE_STD_C11
+	union {
+		uint64_t tx_offload;       /**< combined for easy fetch */
+		__extension__
+		struct {
+			uint64_t l2_len:7;
+			/**< L2 (MAC) Header Length for non-tunneling pkt.
+			 * Outer_L4_len + ... + Inner_L2_len for tunneling pkt.
+			 */
+			uint64_t l3_len:9; /**< L3 (IP) Header Length. */
+			uint64_t l4_len:8; /**< L4 (TCP/UDP) Header Length. */
+			uint64_t tso_segsz:16; /**< TCP TSO segment size */
+
+			/* fields for TX offloading of tunnels */
+			uint64_t outer_l3_len:9; /**< Outer L3 (IP) Hdr Length. */
+			uint64_t outer_l2_len:7; /**< Outer L2 (MAC) Hdr Length. */
+
+			/* uint64_t unused:8; */
+		};
+	};
+
+	/** Size of the application private data. In case of an indirect
+	 * mbuf, it stores the direct mbuf private data size. */
+	uint16_t priv_size;
+
+	/** Timesync flags for use with IEEE1588. */
+	uint16_t timesync;
+} __rte_cache_aligned;
\ No newline at end of file
--- a/third_party/rust/bindgen/tests/headers/no-derive-debug.h
+++ b/third_party/rust/bindgen/tests/headers/no-derive-debug.h
@@ -1,9 +1,9 @@
-// bindgen-flags: --no-derive-debug --blacklist-type foo --raw-line "#[repr(C)] #[derive(Copy, Clone)] pub struct foo { bar: ::std::os::raw::c_int, }"
+// bindgen-flags: --no-derive-debug --blacklist-type foo --raw-line "#[repr(C)] #[derive(Copy, Clone, Default)] pub struct foo { bar: ::std::os::raw::c_int, }"
 
 struct foo {
   int bar;
 };
 
 /**
  * bar should compile. It will normally derive debug, but our blacklist of foo
  * and replacement for another type that doesn't implement it would prevent it
new file mode 100644
--- /dev/null
+++ b/third_party/rust/bindgen/tests/headers/no-derive-default.h
@@ -0,0 +1,15 @@
+// bindgen-flags: --no-derive-default --blacklist-type foo --raw-line "#[repr(C)] #[derive(Copy, Clone, Debug)] pub struct foo { bar: ::std::os::raw::c_int, }"
+
+struct foo {
+  int bar;
+};
+
+/**
+ * bar should compile. It will normally derive default, but our blacklist of foo
+ * and replacement for another type that doesn't implement it would prevent it
+ * from building if --no-derive-default didn't work.
+ */
+struct bar {
+  struct foo foo;
+  int baz;
+};
--- a/third_party/rust/bindgen/tests/headers/objc_method.h
+++ b/third_party/rust/bindgen/tests/headers/objc_method.h
@@ -1,7 +1,11 @@
 // bindgen-flags: --objc-extern-crate -- -x objective-c
 // bindgen-osx-only
 
 @interface Foo
 - (void)method;
-// TODO: argument methods
+- (void)methodWithInt:(int)foo;
+- (void)methodWithFoo:(Foo*)foo;
+- (int)methodReturningInt;
+- (Foo*)methodReturningFoo;
+- (void)methodWithArg1:(int)intvalue andArg2:(char*)ptr andArg3:(float)floatvalue;
 @end
new file mode 100644
--- /dev/null
+++ b/third_party/rust/bindgen/tests/headers/struct_typedef.h
@@ -0,0 +1,15 @@
+typedef struct {
+    _Bool has_name;
+} typedef_named_struct;
+
+typedef struct {
+    void *no_name;
+} *struct_ptr_t, **struct_ptr_ptr_t;
+
+typedef enum {
+    ENUM_HAS_NAME=1
+} typedef_named_enum;
+
+typedef enum {
+    ENUM_IS_ANON
+} *enum_ptr_t, **enum_ptr_ptr_t;
new file mode 100644
--- /dev/null
+++ b/third_party/rust/bindgen/tests/headers/struct_typedef_ns.hpp
@@ -0,0 +1,21 @@
+// bindgen-flags: --enable-cxx-namespaces
+
+namespace whatever {
+    typedef struct {
+        int foo;
+    } typedef_struct;
+
+    typedef enum {
+        BAR=1
+    } typedef_enum;
+}
+
+namespace {
+    typedef struct {
+        int foo;
+    } typedef_struct;
+
+    typedef enum {
+        BAR=1
+    } typedef_enum;
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/bindgen/tests/headers/template_partial_specification.hpp
@@ -0,0 +1,10 @@
+// bindgen-flags: -- --target=x86_64-pc-win32
+
+template<typename Method, bool Cancelable>
+struct nsRunnableMethodTraits;
+
+template<class C, typename R, bool Cancelable, typename... As>
+struct nsRunnableMethodTraits<R(C::*)(As...), Cancelable>
+{
+  static const bool can_cancel = Cancelable;
+};
--- a/third_party/rust/bindgen/tests/headers/unknown_attr.h
+++ b/third_party/rust/bindgen/tests/headers/unknown_attr.h
@@ -1,6 +1,6 @@
 typedef struct {
   long long __clang_max_align_nonce1
       __attribute__((__aligned__(__alignof__(long long))));
-  long double __clang_max_align_nonce2
+  long long __clang_max_align_nonce2
       __attribute__((__aligned__(__alignof__(long double))));
 } max_align_t;
--- a/third_party/rust/bindgen/tests/headers/use-core.h
+++ b/third_party/rust/bindgen/tests/headers/use-core.h
@@ -1,8 +1,13 @@
 // bindgen-flags: --use-core --raw-line "extern crate core;"
 
 struct foo {
   int a, b;
   void* bar;
 };
 
+union {
+  int bar;
+  long baz;
+} bazz;
+
 typedef void (*fooFunction)(int bar);
--- a/third_party/rust/bindgen/tests/tests.rs
+++ b/third_party/rust/bindgen/tests/tests.rs
@@ -79,17 +79,17 @@ fn create_bindgen_builder(header: &PathB
         let line = try!(line);
         if line.contains("bindgen-flags: ") {
             let extra_flags = line.split("bindgen-flags: ")
                 .last()
                 .and_then(shlex::split)
                 .unwrap();
             flags.extend(extra_flags.into_iter());
         } else if line.contains("bindgen-unstable") &&
-                  cfg!(feature = "llvm_stable") {
+                  cfg!(feature = "testing_only_llvm_stable") {
             return Ok(None);
         } else if line.contains("bindgen-osx-only") {
             let prepend_flags = ["--raw-line", "#![cfg(target_os=\"macos\")]"];
             flags = prepend_flags.into_iter()
                 .map(ToString::to_string)
                 .chain(flags)
                 .collect();
         }
@@ -99,30 +99,31 @@ fn create_bindgen_builder(header: &PathB
     // - add "bindgen" as executable name 0th element
     // - add header filename as 1st element
     // - prepend raw lines so they're in the right order for expected output
     // - append the test header's bindgen flags
     let header_str = try!(header.to_str()
         .ok_or(Error::new(ErrorKind::Other, "Invalid header file name")));
 
     let prepend = ["bindgen",
+                   "--with-derive-default",
                    header_str,
                    "--raw-line",
                    "",
                    "--raw-line",
                    "#![allow(non_snake_case)]",
                    "--raw-line",
                    ""];
 
     let args = prepend.into_iter()
         .map(ToString::to_string)
         .chain(flags.into_iter());
 
     builder_from_flags(args)
-        .map(|(builder, _)| Some(builder.no_unstable_rust()))
+        .map(|(builder, _, _)| Some(builder.no_unstable_rust()))
 }
 
 macro_rules! test_header {
     ($function:ident, $header:expr) => (
         #[test]
         fn $function() {
             let header = PathBuf::from($header);
             let result = create_bindgen_builder(&header)
--- 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",".gitattributes":"e753774a5c6c845d5b43db5e4e133c8b7308c233f036517be1e2ae01cb068790",".gitignore":"09cd366a44271073e57584376fd326da166664cd8ff303c2839b63a330557c73",".travis.yml":"0e15437c62f94132e2126b56341c415464f7dc02a35cc0794d8abcc24a2e9585","CHANGELOG.md":"37b2280e140dde6b05ba6e9d40485c6f895681b5c8ccdbee806965901e004673","CONTRIBUTING.md":"51b266af19f050c21549e2ae17445397d9d81eec30bc82490c01a69e288883e6","Cargo.toml":"c6cc9d08f5fdb7681a30704c6a9e0e33f4e4fc48f54775d283afb92fba1fd5fe","LICENSE.txt":"cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30","README.md":"2a21a5fcc9bde7e34984f7d2c65e3fa7c49dcb064944418a58fc77d0ef1f311f","appveyor.yml":"612ad2e0be15a8d339fb8be2fc6ac317d5e6da84886f0f322af399bb1bc28591","build.rs":"804982dacd98f85c0b64d85cb4e96e4f4789a1522e6443674447a1359d6f3e9a","ci/before_install.sh":"025b6b7ac157ea43ab602bf770740929ee45aa6bf6832674c06356c380640230","ci/install.bat":"a81cc40ad9f75fd8448f0f15536c426352ad8ad6809eaf564925b709c458aade","ci/script.sh":"1bb1cd29bd9635cc126cdcbd6c02f3500620a231a86726bf2165a4b74baaf433","ci/test_script.bat":"6240fb92d8d70126deedcf38cab49a31e5fc5364a3b13e7d4bb3e4654b352446","clippy.toml":"acef14b9acffa18d1069ae08a4e8fe824a614f91b0bc71a6b1c68e4d885397e6","src/lib.rs":"67783882b446e3d732fb23e7e5d18986b9546abf8fefbfcec99da12f9b1279cd","src/link.rs":"2f4b9fadc4d565702aa3ef9bc4a9945cd6b68a1e7bd7d0daf74067a4cc624b60","src/support.rs":"c44373478c7ad699740ada941735f9bc49d3e17e5bf3c553683d0143d97171b0","tests/header.h":"b1cf564b21d76db78529d1934e1481a5f0452fdedc6e32954608293c310498b6","tests/lib.rs":"9225ffcaa892a3901c0dce9f8190421db8fb17651499b4de765b87f08daaf5b2"},"package":"822ea22bbbef9f5934e9477860545fb0311a1759e43a276de42e2856c605aa2b"}
\ No newline at end of file
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitattributes":"e753774a5c6c845d5b43db5e4e133c8b7308c233f036517be1e2ae01cb068790",".gitignore":"09cd366a44271073e57584376fd326da166664cd8ff303c2839b63a330557c73",".travis.yml":"0e15437c62f94132e2126b56341c415464f7dc02a35cc0794d8abcc24a2e9585","CHANGELOG.md":"82d4c95ae6437044f9b27f7c6c27d5cc8231bd1e64dda6b8864425b4324d493b","CONTRIBUTING.md":"51b266af19f050c21549e2ae17445397d9d81eec30bc82490c01a69e288883e6","Cargo.toml":"f2da29e9faaae07ab6129fbd259e8d0d313d3a889eaf829c7e7fbef30b65d562","LICENSE.txt":"cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30","README.md":"2a21a5fcc9bde7e34984f7d2c65e3fa7c49dcb064944418a58fc77d0ef1f311f","appveyor.yml":"612ad2e0be15a8d339fb8be2fc6ac317d5e6da84886f0f322af399bb1bc28591","build.rs":"804982dacd98f85c0b64d85cb4e96e4f4789a1522e6443674447a1359d6f3e9a","ci/before_install.sh":"025b6b7ac157ea43ab602bf770740929ee45aa6bf6832674c06356c380640230","ci/install.bat":"a81cc40ad9f75fd8448f0f15536c426352ad8ad6809eaf564925b709c458aade","ci/script.sh":"1bb1cd29bd9635cc126cdcbd6c02f3500620a231a86726bf2165a4b74baaf433","ci/test_script.bat":"6240fb92d8d70126deedcf38cab49a31e5fc5364a3b13e7d4bb3e4654b352446","clippy.toml":"acef14b9acffa18d1069ae08a4e8fe824a614f91b0bc71a6b1c68e4d885397e6","src/lib.rs":"08d988d984de02b1c8549687a9670fd3a835796a558ee07a1d0997b9e35bb6a5","src/link.rs":"2f4b9fadc4d565702aa3ef9bc4a9945cd6b68a1e7bd7d0daf74067a4cc624b60","src/support.rs":"7a3e6dc0eef55766dd4818fadf4fd5be69e0e1d8dab9681ca21da179aaeb1f5f","tests/header.h":"b1cf564b21d76db78529d1934e1481a5f0452fdedc6e32954608293c310498b6","tests/lib.rs":"9225ffcaa892a3901c0dce9f8190421db8fb17651499b4de765b87f08daaf5b2"},"package":"4f98f0715ff67f27ca6a2f8f0ffc2a56f8edbc7acd57489c29eadc3a15c4eafe"}
\ No newline at end of file
--- a/third_party/rust/clang-sys/CHANGELOG.md
+++ b/third_party/rust/clang-sys/CHANGELOG.md
@@ -1,8 +1,20 @@
+## [0.14.0] - 2017-01-30
+
+### Changed
+- Changed all enum types from tuple structs to raw integers to avoid
+  [segmentation faults](https://github.com/rust-lang/rust/issues/39394) on some platforms
+
+## [0.13.0] - 2017-01-29
+
+### Changed
+- Changed all opaque pointers types from tuple structs to raw pointers to avoid
+  [segmentation faults](https://github.com/rust-lang/rust/issues/39394) on some platforms
+
 ## [0.12.0] - 2016-12-13
 
 ### Changed
 - Altered the runtime linking API to allow for testing the presence of functions
 
 ## [0.11.1] - 2016-12-07
 
 ### Added
--- 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.12.0"
+version = "0.14.0"
 
 readme = "README.md"
 license = "Apache-2.0"
 
 description = "Rust bindings for libclang."
 
 documentation = "https://kylemayes.github.io/clang-sys/3_5/clang_sys"
 repository = "https://github.com/KyleMayes/clang-sys"
--- a/third_party/rust/clang-sys/src/lib.rs
+++ b/third_party/rust/clang-sys/src/lib.rs
@@ -40,17 +40,16 @@ extern crate libc;
 extern crate libloading;
 
 pub mod support;
 
 #[macro_use]
 mod link;
 
 use std::mem;
-use std::ptr;
 
 use libc::{c_char, c_int, c_longlong, c_uint, c_ulong, c_ulonglong, c_void, time_t};
 
 pub type CXClientData = *mut c_void;
 pub type CXCursorVisitor = extern fn(CXCursor, CXCursor, CXClientData) -> CXChildVisitResult;
 #[cfg(feature="gte_clang_3_7")]
 pub type CXFieldVisitor = extern fn(CXCursor, CXClientData) -> CXVisitorResult;
 pub type CXInclusionVisitor = extern fn(CXFile, *mut CXSourceLocation, c_uint, CXClientData);
@@ -61,38 +60,19 @@ pub type CXInclusionVisitor = extern fn(
 
 // cenum! ________________________________________
 
 /// Defines a type-safe C enum as a series of constants.
 macro_rules! cenum {
     ($(#[$meta:meta])* enum $name:ident {
         $($(#[$vmeta:meta])* const $variant:ident = $value:expr), +,
     }) => (
-        #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
-        #[repr(C)]
-        pub struct $name(c_int);
-
-        impl $name {
-            //- Constructors ---------------------
+        pub type $name = c_int;
 
-            /// Constructs an instance of this C enum from the supplied discriminant if possible.
-            pub fn from_raw(discriminant: c_int) -> Option<$name> {
-                $(if discriminant == $value { return Some($variant); })+
-                None
-            }
-
-            //- Accessors ------------------------
-
-            /// Returns the discriminant for this C enum.
-            pub fn to_raw(self) -> c_int {
-                self.0
-            }
-        }
-
-        $($(#[$vmeta])* pub const $variant: $name = $name($value);)+
+        $($(#[$vmeta])* pub const $variant: $name = $value;)+
     );
 }
 
 // default! ______________________________________
 
 /// Implements a zeroing implementation of `Default` for the supplied type.
 macro_rules! default {
     (#[$meta:meta] $ty:ty) => {
@@ -942,37 +922,17 @@ bitflags! {
 }
 
 //================================================
 // Structs
 //================================================
 
 // Opaque ________________________________________
 
-macro_rules! opaque {
-    ($name:ident) => (
-        #[derive(Copy, Clone, Debug)]
-        #[repr(C)]
-        pub struct $name(pub *mut c_void);
-
-        impl Default for $name {
-            fn default() -> $name {
-                $name(ptr::null_mut())
-            }
-        }
-
-        impl std::ops::Deref for $name {
-            type Target = *mut c_void;
-
-            fn deref(&self) -> &Self::Target {
-                &self.0
-            }
-        }
-    );
-}
+macro_rules! opaque { ($name:ident) => (pub type $name = *mut c_void;); }
 
 opaque!(CXCompilationDatabase);
 opaque!(CXCompileCommand);
 opaque!(CXCompileCommands);
 opaque!(CXCompletionString);
 opaque!(CXCursorSet);
 opaque!(CXDiagnostic);
 opaque!(CXDiagnosticSet);
--- a/third_party/rust/clang-sys/src/support.rs
+++ b/third_party/rust/clang-sys/src/support.rs
@@ -136,17 +136,18 @@ fn run(executable: &str, arguments: &[&s
 
 /// Runs `clang`, returning the `stdout` and `stderr` output.
 fn run_clang(path: &Path, arguments: &[&str]) -> (String, String) {
     run(&path.to_string_lossy().into_owned(), arguments).unwrap()
 }
 
 /// Runs `llvm-config`, returning the `stdout` output if successful.
 fn run_llvm_config(arguments: &[&str]) -> Result<String, String> {
-    run(&env::var("LLVM_CONFIG_PATH").unwrap_or("llvm-config".into()), arguments).map(|(o, _)| o)
+    let config = env::var("LLVM_CONFIG_PATH").unwrap_or_else(|_| "llvm-config".to_string());
+    run(&config, arguments).map(|(o, _)| o)
 }
 
 /// Parses a version number if possible, ignoring trailing non-digit characters.
 fn parse_version_number(number: &str) -> Option<c_int> {
     number.chars().take_while(|c| c.is_digit(10)).collect::<String>().parse().ok()
 }
 
 /// Parses the version from the output of a `clang` executable if possible.
--- a/third_party/rust/cssparser/.cargo-checksum.json
+++ b/third_party/rust/cssparser/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"e32812a8f09b0c5b0b972e2e090f8929eb5b600a37ca7aac2ed07ba10c30291e",".travis.yml":"f1fb4b65964c81bc1240544267ea334f554ca38ae7a74d57066f4d47d2b5d568","Cargo.toml":"0540b9b26bd82d5d06c49a388819386a56747a3f6e373404c72596b075374af3","LICENSE":"fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85","README.md":"9afe084d70a5d9396674a2624012d6ac749df35f81e322d2d75b042bf208f523","build.rs":"f939ec77d81805b32793e0d7bb447133011a958c678e594ee4d1a6ec8e553cda","docs/.nojekyll":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","docs/404.html":"025861f76f8d1f6d67c20ab624c6e418f4f824385e2dd8ad8732c4ea563c6a2e","docs/index.html":"025861f76f8d1f6d67c20ab624c6e418f4f824385e2dd8ad8732c4ea563c6a2e","src/big-data-url.css":"04a8f6197ea1181123bca48bd1ebd016268e1da40f01b8f21055814e44bf62b8","src/color.rs":"791631f74eb68a6eb2a97f06c766d5a824f3ba3af8a1d39379a81abb974a58a1","src/css-parsing-tests/An+B.json":"d24559c1dad55d3da9d1fca29383edefdfc6046988435d6388a9bc0f28850257","src/css-parsing-tests/LICENSE":"5f9019a92f4aa8917aadc8e035aa673c2c1bf08d5ca2e535a0564106599f44eb","src/css-parsing-tests/README.rst":"35772ce9dcff12a7f8696681a640c6ade18065928b9c02441221ad0622084ef4","src/css-parsing-tests/color3.json":"71ec4107b7bcac029350f9969c1576ee8875543c2fb9ff01354728c3349930fb","src/css-parsing-tests/color3_hsl.json":"c7bfa20bbb1de9378f70b403091f49af834c59e13303155eed4bc73cafa0eab4","src/css-parsing-tests/color3_keywords.json":"30804795eb8445d323a06c70a9d1e52b34c35566dcfd607bc43550f6b6f17d1e","src/css-parsing-tests/component_value_list.json":"5c4ebf91544f7ef903bb67f35c07bcb9e70e4c5e69e71bd1a815f95113fa733a","src/css-parsing-tests/declaration_list.json":"0b85cc3f19e945f838432acbfb9edb003abea13debc4ea27bcdcef25d117eac5","src/css-parsing-tests/make_color3_hsl.py":"d460afc9b2f8d72724482ae03959604928d5cc52a007b33854fc1bbf9d209ca3","src/css-parsing-tests/make_color3_keywords.py":"e91a91d1922c9a7eea0bcd7749e6006deb4e67d3ce7aca6b8dfff65a11be15a5","src/css-parsing-tests/one_component_value.json":"8798017709002e14cf11e203c9d716f82d308ce6ba0f6e64ee4eea331b8485c6","src/css-parsing-tests/one_declaration.json":"a34c9da56edfff9e2e21615f059e141b0e878e90f794dc8fa58d65b47cd193ed","src/css-parsing-tests/one_rule.json":"88f7b1b6049be88e1e2827673b75fc9261986b216e8ee6bf09621fecbe274e3c","src/css-parsing-tests/rule_list.json":"97c45e80fb83abef149a4016c5625a74f053e7ad70a2ce5a95c02fce1c195686","src/css-parsing-tests/stylesheet.json":"05f1e10fc486bfbda2c059c313a74ff78c0063c0768b99737cab41969c0c87ce","src/css-parsing-tests/stylesheet_bytes.json":"890fd856a596e61f82cf7ed77920ffe95df89209fdb5ee0afe0b26bdfdb80a42","src/from_bytes.rs":"d41f744ebd0bf285004c984804a7513221e1ae87bb07200f866e24f7f110655b","src/lib.rs":"4a78ca5130915646375a7760d8c4b4b9b9129814efb0e5b26235196e0d89be32","src/macros/match_byte.rs":"89e8b941af74df2c204abf808672d3ff278bdec75abc918c41a843260b924677","src/macros/mod.rs":"99ffb7c3dbb5a09c7363db84a6ea439ab848439615b37a2e420710c5be3fbde2","src/nth.rs":"9dcabe79ab33c9965cf12fedd649f211e268572fc620f555b5dd28bbc7bea5b2","src/parser.rs":"99739b79e0829d868fc9d3ded5a20d54023dd4ff4bd71f2d0bf8e20df4f395ac","src/rules_and_declarations.rs":"6b66a986e411a56998546ab0e64de5285df3368d7c4018c7230a1b6cf6bcc532","src/serializer.rs":"e5b64fbf20f3a67917939adfa9adea9450d1b898e21f41ec7bc8bad8626f557b","src/tests.rs":"0538141d3a7c973c8e3c93c994b2814d8398239f6bc1ecdefc8050f47fcb7d3e","src/tokenizer.rs":"fd4d019402838bf4c7b3cb9a54f4abb94c2722c7ada4df53829e2bc1f33828a4"},"package":"d8e562cb0d6ee9d8c367d3801d4dbaa0a0a94807745f710803b4ec4cf723ddd4"}
\ No newline at end of file
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"e32812a8f09b0c5b0b972e2e090f8929eb5b600a37ca7aac2ed07ba10c30291e",".travis.yml":"f1fb4b65964c81bc1240544267ea334f554ca38ae7a74d57066f4d47d2b5d568","Cargo.toml":"70c260c12658b0f3a219ff074030b92ab06747b6ea6d11bb59e66d3cc986c2cc","LICENSE":"fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85","README.md":"9afe084d70a5d9396674a2624012d6ac749df35f81e322d2d75b042bf208f523","build.rs":"56bfa720a5982d724661a8029315e801258e67245354aabaf2120b73f853cf3c","docs/.nojekyll":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","docs/404.html":"025861f76f8d1f6d67c20ab624c6e418f4f824385e2dd8ad8732c4ea563c6a2e","docs/index.html":"025861f76f8d1f6d67c20ab624c6e418f4f824385e2dd8ad8732c4ea563c6a2e","src/big-data-url.css":"04a8f6197ea1181123bca48bd1ebd016268e1da40f01b8f21055814e44bf62b8","src/color.rs":"a1e82da32c8462b811393f9be19710221a44fab4546596e9a65c5ef8df459c8f","src/css-parsing-tests/An+B.json":"d24559c1dad55d3da9d1fca29383edefdfc6046988435d6388a9bc0f28850257","src/css-parsing-tests/LICENSE":"5f9019a92f4aa8917aadc8e035aa673c2c1bf08d5ca2e535a0564106599f44eb","src/css-parsing-tests/README.rst":"775c5f957dd1d46d3ce954aaad219c821d2b64b4a9fb93c42e9737a11131ca44","src/css-parsing-tests/color3.json":"008f080f6f2dbae5ee403ff46aaa40a9a16e68a2b8923446ac6374f04da9e868","src/css-parsing-tests/color3_hsl.json":"09a4a1e51fb78276cdbf2e834cc9234f5b97c35426ddc879e35b2b09990327b5","src/css-parsing-tests/color3_keywords.json":"95609bf9fe762c316878a30f371fa375a2e51c21a6fda24fa188a95cd9118f5c","src/css-parsing-tests/component_value_list.json":"dda7244eb3a4fcf6d296762e285f7031028837d987065a09e584e8d973edc7f3","src/css-parsing-tests/declaration_list.json":"0b85cc3f19e945f838432acbfb9edb003abea13debc4ea27bcdcef25d117eac5","src/css-parsing-tests/make_color3_hsl.py":"df6f4c154c098641aab81d030de53c65d75d9bde429e9d1ff7069cc5b1827031","src/css-parsing-tests/make_color3_keywords.py":"66bccab3f1dea18698fcfd854be79b1fd1cd724dd487e25b1f057b522163aad2","src/css-parsing-tests/one_component_value.json":"8798017709002e14cf11e203c9d716f82d308ce6ba0f6e64ee4eea331b8485c6","src/css-parsing-tests/one_declaration.json":"a34c9da56edfff9e2e21615f059e141b0e878e90f794dc8fa58d65b47cd193ed","src/css-parsing-tests/one_rule.json":"88f7b1b6049be88e1e2827673b75fc9261986b216e8ee6bf09621fecbe274e3c","src/css-parsing-tests/rule_list.json":"97c45e80fb83abef149a4016c5625a74f053e7ad70a2ce5a95c02fce1c195686","src/css-parsing-tests/stylesheet.json":"05f1e10fc486bfbda2c059c313a74ff78c0063c0768b99737cab41969c0c87ce","src/css-parsing-tests/stylesheet_bytes.json":"890fd856a596e61f82cf7ed77920ffe95df89209fdb5ee0afe0b26bdfdb80a42","src/css-parsing-tests/urange.json":"7ce494811fcb64f20597bd11c88dc99bd72445290582e280bf7774f5d15e1ed3","src/from_bytes.rs":"331fe63af2123ae3675b61928a69461b5ac77799fff3ce9978c55cf2c558f4ff","src/lib.rs":"233ff7a7576512cbcde0221df06256bcd68c495dd2534b582832b4012518d8a8","src/macros/match_byte.rs":"89e8b941af74df2c204abf808672d3ff278bdec75abc918c41a843260b924677","src/macros/mod.rs":"99ffb7c3dbb5a09c7363db84a6ea439ab848439615b37a2e420710c5be3fbde2","src/nth.rs":"9dcabe79ab33c9965cf12fedd649f211e268572fc620f555b5dd28bbc7bea5b2","src/parser.rs":"99739b79e0829d868fc9d3ded5a20d54023dd4ff4bd71f2d0bf8e20df4f395ac","src/rules_and_declarations.rs":"6b66a986e411a56998546ab0e64de5285df3368d7c4018c7230a1b6cf6bcc532","src/serializer.rs":"4521b58389bd57acced55c3c6130831b7f80eff48ef873c48c5363e0eca0a15c","src/tests.rs":"10e2f5358b4bbbb58ef4ee5fcff5e86db1bbc3462ee892de2171f63cb46125c3","src/tokenizer.rs":"ef1f220224365d46299160191facd2d9e0534e10ef362129cf56cd3dbb87106a","src/unicode_range.rs":"a3accaf00b8e0e93ba9af0863024507b97ddc2646e65c5f7421597a269317ac0"},"package":"e99bbf5004f7a9cbba7cac7b83320b88eea4008f227c842d4ff2de4b99147352"}
\ No newline at end of file
--- a/third_party/rust/cssparser/Cargo.toml
+++ b/third_party/rust/cssparser/Cargo.toml
@@ -1,30 +1,33 @@
 [package]
 
 name = "cssparser"
-version = "0.7.4"
+version = "0.9.0"
 authors = [ "Simon Sapin <simon.sapin@exyr.org>" ]
 
 description = "Rust implementation of CSS Syntax Level 3"
 documentation = "http://servo.github.io/rust-cssparser/cssparser/index.html"
 repository = "https://github.com/servo/rust-cssparser"
 readme = "README.md"
 keywords = ["css", "syntax", "parser"]
 license = "MPL-2.0"
 build = "build.rs"
 
 exclude = ["src/css-parsing-tests"]
 
+[lib]
+doctest = false
+
 [dev-dependencies]
 rustc-serialize = "0.3"
 tempdir = "0.3"
+encoding_rs = "0.3.2"
 
 [dependencies]
-encoding = "0.2"
 heapsize = {version = ">=0.1.1, <0.4.0", optional = true}
 matches = "0.1"
 serde = {version = ">=0.6.6, <0.9", optional = true}
 
 [build-dependencies]
 syn = { version = "0.10.6", features = ["full", "visit"]}
 quote = "0.3"
 
--- a/third_party/rust/cssparser/build.rs
+++ b/third_party/rust/cssparser/build.rs
@@ -1,13 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#[macro_use] extern crate quote;
+extern crate quote;
 extern crate syn;
 
 use std::env;
 use std::path::Path;
 
 
 #[cfg(feature = "dummy_match_byte")]
 mod codegen {
--- a/third_party/rust/cssparser/src/color.rs
+++ b/third_party/rust/cssparser/src/color.rs
@@ -1,73 +1,117 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+use std::cmp;
 use std::fmt;
 
 use super::{Token, Parser, ToCss};
+use tokenizer::NumericValue;
 
 #[cfg(feature = "serde")]
 use serde::{Deserialize, Deserializer, Serialize, Serializer};
 
-/// A color with red, green, blue, and alpha components.
+/// A color with red, green, blue, and alpha components, in a byte each.
 #[derive(Clone, Copy, PartialEq, Debug)]
 pub struct RGBA {
-    /// The red channel. Nominally in 0.0 ... 1.0.
-    pub red: f32,
-    /// The green channel. Nominally in 0.0 ... 1.0.
-    pub green: f32,
-    /// The blue channel. Nominally in 0.0 ... 1.0.
-    pub blue: f32,
-    /// The alpha (opacity) channel. Clamped to 0.0 ... 1.0.
-    pub alpha: f32,
+    /// The red component.
+    pub red: u8,
+    /// The green component.
+    pub green: u8,
+    /// The blue component.
+    pub blue: u8,
+    /// The alpha component.
+    pub alpha: u8,
+}
+
+impl RGBA {
+    /// Constructs a new RGBA value from float components. It expects the red,
+    /// green, blue and alpha channels in that order, and all values will be
+    /// clamped to the 0.0 ... 1.0 range.
+    #[inline]
+    pub fn from_floats(red: f32, green: f32, blue: f32, alpha: f32) -> Self {
+        Self::new(clamp_f32(red), clamp_f32(green), clamp_f32(blue), clamp_f32(alpha))
+    }
+
+    /// Returns a transparent color.
+    #[inline]
+    pub fn transparent() -> Self {
+        Self::new(0, 0, 0, 0)
+    }
+
+    /// Same thing, but with `u8` values instead of floats in the 0 to 1 range.
+    #[inline]
+    pub fn new(red: u8, green: u8, blue: u8, alpha: u8) -> Self {
+        RGBA { red: red, green: green, blue: blue, alpha: alpha }
+    }
+
+    /// Returns the red channel in a floating point number form, from 0 to 1.
+    #[inline]
+    pub fn red_f32(&self) -> f32 {
+        self.red as f32 / 255.0
+    }
+
+    /// Returns the green channel in a floating point number form, from 0 to 1.
+    #[inline]
+    pub fn green_f32(&self) -> f32 {
+        self.green as f32 / 255.0
+    }
+
+    /// Returns the blue channel in a floating point number form, from 0 to 1.
+    #[inline]
+    pub fn blue_f32(&self) -> f32 {
+        self.blue as f32 / 255.0
+    }
+
+    /// Returns the alpha channel in a floating point number form, from 0 to 1.
+    #[inline]
+    pub fn alpha_f32(&self) -> f32 {
+        self.alpha as f32 / 255.0
+    }
 }
 
 #[cfg(feature = "serde")]
 impl Serialize for RGBA {
     fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
         where S: Serializer
     {
         (self.red, self.green, self.blue, self.alpha).serialize(serializer)
     }
 }
 
 #[cfg(feature = "serde")]
 impl Deserialize for RGBA {
     fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
         where D: Deserializer
     {
-        let (red, green, blue, alpha) =
-            try!(Deserialize::deserialize(deserializer));
-        Ok(RGBA {
-            red: red,
-            green: green,
-            blue: blue,
-            alpha: alpha,
-        })
+        let (r, g, b, a) = try!(Deserialize::deserialize(deserializer));
+        Ok(RGBA::new(r, g, b, a))
     }
 }
 
 #[cfg(feature = "heapsize")]
 known_heap_size!(0, RGBA);
 
 impl ToCss for RGBA {
-    fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
-        if self.alpha == 1f32 {
-            write!(dest, "rgb({}, {}, {})",
-                   (self.red * 255.).round(),
-                   (self.green * 255.).round(),
-                   (self.blue * 255.).round())
+    fn to_css<W>(&self, dest: &mut W) -> fmt::Result
+        where W: fmt::Write,
+    {
+        // Try first with two decimal places, then with three.
+        let mut rounded_alpha = (self.alpha_f32() * 100.).round() / 100.;
+        if clamp_f32(rounded_alpha) != self.alpha {
+            rounded_alpha = (self.alpha_f32() * 1000.).round() / 1000.;
+        }
+
+        if self.alpha == 255 {
+            write!(dest, "rgb({}, {}, {})", self.red, self.green, self.blue)
         } else {
             write!(dest, "rgba({}, {}, {}, {})",
-                   (self.red * 255.).round(),
-                   (self.green * 255.).round(),
-                   (self.blue * 255.).round(),
-                   self.alpha)
+                   self.red, self.green, self.blue, rounded_alpha)
         }
     }
 }
 
 /// A <color> value.
 #[derive(Clone, Copy, PartialEq, Debug)]
 pub enum Color {
     /// The 'currentColor' keyword
@@ -76,19 +120,19 @@ pub enum Color {
     RGBA(RGBA),
 }
 
 #[cfg(feature = "heapsize")]
 known_heap_size!(0, Color);
 
 impl ToCss for Color {
     fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
-        match self {
-            &Color::CurrentColor => dest.write_str("currentColor"),
-            &Color::RGBA(rgba) => rgba.to_css(dest),
+        match *self {
+            Color::CurrentColor => dest.write_str("currentColor"),
+            Color::RGBA(ref rgba) => rgba.to_css(dest),
         }
     }
 }
 
 impl Color {
     /// Parse a <color> value, per CSS Color Module Level 3.
     ///
     /// FIXME(#2) Deprecated CSS2 System Colors are not supported yet.
@@ -103,195 +147,185 @@ impl Color {
             }
             _ => Err(())
         }
     }
 }
 
 
 #[inline]
-fn rgb(red: f32, green: f32, blue: f32) -> Result<Color, ()> {
-    Ok(Color::RGBA(RGBA {
-        red: red / 255.,
-        green: green / 255.,
-        blue: blue / 255.,
-        alpha: 1.,
-    }))
+fn rgb(red: u8, green: u8, blue: u8) -> Result<Color, ()> {
+    rgba(red, green, blue, 255)
 }
 
 #[inline]
-fn rgba(red: f32, green: f32, blue: f32, alpha: f32) -> Result<Color, ()> {
-    Ok(Color::RGBA(RGBA {
-        red: red / 255.,
-        green: green / 255.,
-        blue: blue / 255.,
-        alpha: alpha / 255.,
-    }))
+fn rgba(red: u8, green: u8, blue: u8, alpha: u8) -> Result<Color, ()> {
+    Ok(Color::RGBA(RGBA::new(red, green, blue, alpha)))
 }
 
 
 /// Return the named color with the given name.
 ///
 /// Matching is case-insensitive in the ASCII range.
 /// CSS escaping (if relevant) should be resolved before calling this function.
 /// (For example, the value of an `Ident` token is fine.)
 #[inline]
 pub fn parse_color_keyword(ident: &str) -> Result<Color, ()> {
     match_ignore_ascii_case! { ident,
-        "black" => rgb(0., 0., 0.),
-        "silver" => rgb(192., 192., 192.),
-        "gray" => rgb(128., 128., 128.),
-        "white" => rgb(255., 255., 255.),
-        "maroon" => rgb(128., 0., 0.),
-        "red" => rgb(255., 0., 0.),
-        "purple" => rgb(128., 0., 128.),
-        "fuchsia" => rgb(255., 0., 255.),
-        "green" => rgb(0., 128., 0.),
-        "lime" => rgb(0., 255., 0.),
-        "olive" => rgb(128., 128., 0.),
-        "yellow" => rgb(255., 255., 0.),
-        "navy" => rgb(0., 0., 128.),
-        "blue" => rgb(0., 0., 255.),
-        "teal" => rgb(0., 128., 128.),
-        "aqua" => rgb(0., 255., 255.),
+        "black" => rgb(0, 0, 0),
+        "silver" => rgb(192, 192, 192),
+        "gray" => rgb(128, 128, 128),
+        "white" => rgb(255, 255, 255),
+        "maroon" => rgb(128, 0, 0),
+        "red" => rgb(255, 0, 0),
+        "purple" => rgb(128, 0, 128),
+        "fuchsia" => rgb(255, 0, 255),
+        "green" => rgb(0, 128, 0),
+        "lime" => rgb(0, 255, 0),
+        "olive" => rgb(128, 128, 0),
+        "yellow" => rgb(255, 255, 0),
+        "navy" => rgb(0, 0, 128),
+        "blue" => rgb(0, 0, 255),
+        "teal" => rgb(0, 128, 128),
+        "aqua" => rgb(0, 255, 255),
 
-        "aliceblue" => rgb(240., 248., 255.),
-        "antiquewhite" => rgb(250., 235., 215.),
-        "aquamarine" => rgb(127., 255., 212.),
-        "azure" => rgb(240., 255., 255.),
-        "beige" => rgb(245., 245., 220.),
-        "bisque" => rgb(255., 228., 196.),
-        "blanchedalmond" => rgb(255., 235., 205.),
-        "blueviolet" => rgb(138., 43., 226.),
-        "brown" => rgb(165., 42., 42.),
-        "burlywood" => rgb(222., 184., 135.),
-        "cadetblue" => rgb(95., 158., 160.),
-        "chartreuse" => rgb(127., 255., 0.),
-        "chocolate" => rgb(210., 105., 30.),
-        "coral" => rgb(255., 127., 80.),
-        "cornflowerblue" => rgb(100., 149., 237.),
-        "cornsilk" => rgb(255., 248., 220.),
-        "crimson" => rgb(220., 20., 60.),
-        "cyan" => rgb(0., 255., 255.),
-        "darkblue" => rgb(0., 0., 139.),
-        "darkcyan" => rgb(0., 139., 139.),
-        "darkgoldenrod" => rgb(184., 134., 11.),
-        "darkgray" => rgb(169., 169., 169.),
-        "darkgreen" => rgb(0., 100., 0.),
-        "darkgrey" => rgb(169., 169., 169.),
-        "darkkhaki" => rgb(189., 183., 107.),
-        "darkmagenta" => rgb(139., 0., 139.),
-        "darkolivegreen" => rgb(85., 107., 47.),
-        "darkorange" => rgb(255., 140., 0.),
-        "darkorchid" => rgb(153., 50., 204.),
-        "darkred" => rgb(139., 0., 0.),
-        "darksalmon" => rgb(233., 150., 122.),
-        "darkseagreen" => rgb(143., 188., 143.),
-        "darkslateblue" => rgb(72., 61., 139.),
-        "darkslategray" => rgb(47., 79., 79.),
-        "darkslategrey" => rgb(47., 79., 79.),
-        "darkturquoise" => rgb(0., 206., 209.),
-        "darkviolet" => rgb(148., 0., 211.),
-        "deeppink" => rgb(255., 20., 147.),
-        "deepskyblue" => rgb(0., 191., 255.),
-        "dimgray" => rgb(105., 105., 105.),
-        "dimgrey" => rgb(105., 105., 105.),
-        "dodgerblue" => rgb(30., 144., 255.),
-        "firebrick" => rgb(178., 34., 34.),
-        "floralwhite" => rgb(255., 250., 240.),
-        "forestgreen" => rgb(34., 139., 34.),
-        "gainsboro" => rgb(220., 220., 220.),
-        "ghostwhite" => rgb(248., 248., 255.),
-        "gold" => rgb(255., 215., 0.),
-        "goldenrod" => rgb(218., 165., 32.),
-        "greenyellow" => rgb(173., 255., 47.),
-        "grey" => rgb(128., 128., 128.),
-        "honeydew" => rgb(240., 255., 240.),
-        "hotpink" => rgb(255., 105., 180.),
-        "indianred" => rgb(205., 92., 92.),
-        "indigo" => rgb(75., 0., 130.),
-        "ivory" => rgb(255., 255., 240.),
-        "khaki" => rgb(240., 230., 140.),
-        "lavender" => rgb(230., 230., 250.),
-        "lavenderblush" => rgb(255., 240., 245.),
-        "lawngreen" => rgb(124., 252., 0.),
-        "lemonchiffon" => rgb(255., 250., 205.),
-        "lightblue" => rgb(173., 216., 230.),
-        "lightcoral" => rgb(240., 128., 128.),
-        "lightcyan" => rgb(224., 255., 255.),
-        "lightgoldenrodyellow" => rgb(250., 250., 210.),
-        "lightgray" => rgb(211., 211., 211.),
-        "lightgreen" => rgb(144., 238., 144.),
-        "lightgrey" => rgb(211., 211., 211.),
-        "lightpink" => rgb(255., 182., 193.),
-        "lightsalmon" => rgb(255., 160., 122.),
-        "lightseagreen" => rgb(32., 178., 170.),
-        "lightskyblue" => rgb(135., 206., 250.),
-        "lightslategray" => rgb(119., 136., 153.),
-        "lightslategrey" => rgb(119., 136., 153.),
-        "lightsteelblue" => rgb(176., 196., 222.),
-        "lightyellow" => rgb(255., 255., 224.),
-        "limegreen" => rgb(50., 205., 50.),
-        "linen" => rgb(250., 240., 230.),
-        "magenta" => rgb(255., 0., 255.),
-        "mediumaquamarine" => rgb(102., 205., 170.),
-        "mediumblue" => rgb(0., 0., 205.),
-        "mediumorchid" => rgb(186., 85., 211.),
-        "mediumpurple" => rgb(147., 112., 219.),
-        "mediumseagreen" => rgb(60., 179., 113.),
-        "mediumslateblue" => rgb(123., 104., 238.),
-        "mediumspringgreen" => rgb(0., 250., 154.),
-        "mediumturquoise" => rgb(72., 209., 204.),
-        "mediumvioletred" => rgb(199., 21., 133.),
-        "midnightblue" => rgb(25., 25., 112.),
-        "mintcream" => rgb(245., 255., 250.),
-        "mistyrose" => rgb(255., 228., 225.),
-        "moccasin" => rgb(255., 228., 181.),
-        "navajowhite" => rgb(255., 222., 173.),
-        "oldlace" => rgb(253., 245., 230.),
-        "olivedrab" => rgb(107., 142., 35.),
-        "orange" => rgb(255., 165., 0.),
-        "orangered" => rgb(255., 69., 0.),
-        "orchid" => rgb(218., 112., 214.),
-        "palegoldenrod" => rgb(238., 232., 170.),
-        "palegreen" => rgb(152., 251., 152.),
-        "paleturquoise" => rgb(175., 238., 238.),
-        "palevioletred" => rgb(219., 112., 147.),
-        "papayawhip" => rgb(255., 239., 213.),
-        "peachpuff" => rgb(255., 218., 185.),
-        "peru" => rgb(205., 133., 63.),
-        "pink" => rgb(255., 192., 203.),
-        "plum" => rgb(221., 160., 221.),
-        "powderblue" => rgb(176., 224., 230.),
-        "rebeccapurple" => rgb(102., 51., 153.),
-        "rosybrown" => rgb(188., 143., 143.),
-        "royalblue" => rgb(65., 105., 225.),
-        "saddlebrown" => rgb(139., 69., 19.),
-        "salmon" => rgb(250., 128., 114.),
-        "sandybrown" => rgb(244., 164., 96.),
-        "seagreen" => rgb(46., 139., 87.),
-        "seashell" => rgb(255., 245., 238.),
-        "sienna" => rgb(160., 82., 45.),
-        "skyblue" => rgb(135., 206., 235.),
-        "slateblue" => rgb(106., 90., 205.),
-        "slategray" => rgb(112., 128., 144.),
-        "slategrey" => rgb(112., 128., 144.),
-        "snow" => rgb(255., 250., 250.),
-        "springgreen" => rgb(0., 255., 127.),
-        "steelblue" => rgb(70., 130., 180.),
-        "tan" => rgb(210., 180., 140.),
-        "thistle" => rgb(216., 191., 216.),
-        "tomato" => rgb(255., 99., 71.),
-        "turquoise" => rgb(64., 224., 208.),
-        "violet" => rgb(238., 130., 238.),
-        "wheat" => rgb(245., 222., 179.),
-        "whitesmoke" => rgb(245., 245., 245.),
-        "yellowgreen" => rgb(154., 205., 50.),
+        "aliceblue" => rgb(240, 248, 255),
+        "antiquewhite" => rgb(250, 235, 215),
+        "aquamarine" => rgb(127, 255, 212),
+        "azure" => rgb(240, 255, 255),
+        "beige" => rgb(245, 245, 220),
+        "bisque" => rgb(255, 228, 196),
+        "blanchedalmond" => rgb(255, 235, 205),
+        "blueviolet" => rgb(138, 43, 226),
+        "brown" => rgb(165, 42, 42),
+        "burlywood" => rgb(222, 184, 135),
+        "cadetblue" => rgb(95, 158, 160),
+        "chartreuse" => rgb(127, 255, 0),
+        "chocolate" => rgb(210, 105, 30),
+        "coral" => rgb(255, 127, 80),
+        "cornflowerblue" => rgb(100, 149, 237),
+        "cornsilk" => rgb(255, 248, 220),
+        "crimson" => rgb(220, 20, 60),
+        "cyan" => rgb(0, 255, 255),
+        "darkblue" => rgb(0, 0, 139),
+        "darkcyan" => rgb(0, 139, 139),
+        "darkgoldenrod" => rgb(184, 134, 11),
+        "darkgray" => rgb(169, 169, 169),
+        "darkgreen" => rgb(0, 100, 0),
+        "darkgrey" => rgb(169, 169, 169),
+        "darkkhaki" => rgb(189, 183, 107),
+        "darkmagenta" => rgb(139, 0, 139),
+        "darkolivegreen" => rgb(85, 107, 47),
+        "darkorange" => rgb(255, 140, 0),
+        "darkorchid" => rgb(153, 50, 204),
+        "darkred" => rgb(139, 0, 0),
+        "darksalmon" => rgb(233, 150, 122),
+        "darkseagreen" => rgb(143, 188, 143),
+        "darkslateblue" => rgb(72, 61, 139),
+        "darkslategray" => rgb(47, 79, 79),
+        "darkslategrey" => rgb(47, 79, 79),
+        "darkturquoise" => rgb(0, 206, 209),
+        "darkviolet" => rgb(148, 0, 211),
+        "deeppink" => rgb(255, 20, 147),
+        "deepskyblue" => rgb(0, 191, 255),
+        "dimgray" => rgb(105, 105, 105),
+        "dimgrey" => rgb(105, 105, 105),
+        "dodgerblue" => rgb(30, 144, 255),
+        "firebrick" => rgb(178, 34, 34),
+        "floralwhite" => rgb(255, 250, 240),
+        "forestgreen" => rgb(34, 139, 34),
+        "gainsboro" => rgb(220, 220, 220),
+        "ghostwhite" => rgb(248, 248, 255),
+        "gold" => rgb(255, 215, 0),
+        "goldenrod" => rgb(218, 165, 32),
+        "greenyellow" => rgb(173, 255, 47),
+        "grey" => rgb(128, 128, 128),
+        "honeydew" => rgb(240, 255, 240),
+        "hotpink" => rgb(255, 105, 180),
+        "indianred" => rgb(205, 92, 92),
+        "indigo" => rgb(75, 0, 130),
+        "ivory" => rgb(255, 255, 240),
+        "khaki" => rgb(240, 230, 140),
+        "lavender" => rgb(230, 230, 250),
+        "lavenderblush" => rgb(255, 240, 245),
+        "lawngreen" => rgb(124, 252, 0),
+        "lemonchiffon" => rgb(255, 250, 205),
+        "lightblue" => rgb(173, 216, 230),
+        "lightcoral" => rgb(240, 128, 128),
+        "lightcyan" => rgb(224, 255, 255),
+        "lightgoldenrodyellow" => rgb(250, 250, 210),
+        "lightgray" => rgb(211, 211, 211),
+        "lightgreen" => rgb(144, 238, 144),
+        "lightgrey" => rgb(211, 211, 211),
+        "lightpink" => rgb(255, 182, 193),
+        "lightsalmon" => rgb(255, 160, 122),
+        "lightseagreen" => rgb(32, 178, 170),
+        "lightskyblue" => rgb(135, 206, 250),
+        "lightslategray" => rgb(119, 136, 153),
+        "lightslategrey" => rgb(119, 136, 153),
+        "lightsteelblue" => rgb(176, 196, 222),
+        "lightyellow" => rgb(255, 255, 224),
+        "limegreen" => rgb(50, 205, 50),
+        "linen" => rgb(250, 240, 230),
+        "magenta" => rgb(255, 0, 255),
+        "mediumaquamarine" => rgb(102, 205, 170),
+        "mediumblue" => rgb(0, 0, 205),
+        "mediumorchid" => rgb(186, 85, 211),
+        "mediumpurple" => rgb(147, 112, 219),
+        "mediumseagreen" => rgb(60, 179, 113),
+        "mediumslateblue" => rgb(123, 104, 238),
+        "mediumspringgreen" => rgb(0, 250, 154),
+        "mediumturquoise" => rgb(72, 209, 204),
+        "mediumvioletred" => rgb(199, 21, 133),
+        "midnightblue" => rgb(25, 25, 112),
+        "mintcream" => rgb(245, 255, 250),
+        "mistyrose" => rgb(255, 228, 225),
+        "moccasin" => rgb(255, 228, 181),
+        "navajowhite" => rgb(255, 222, 173),
+        "oldlace" => rgb(253, 245, 230),
+        "olivedrab" => rgb(107, 142, 35),
+        "orange" => rgb(255, 165, 0),
+        "orangered" => rgb(255, 69, 0),
+        "orchid" => rgb(218, 112, 214),
+        "palegoldenrod" => rgb(238, 232, 170),
+        "palegreen" => rgb(152, 251, 152),
+        "paleturquoise" => rgb(175, 238, 238),
+        "palevioletred" => rgb(219, 112, 147),
+        "papayawhip" => rgb(255, 239, 213),
+        "peachpuff" => rgb(255, 218, 185),
+        "peru" => rgb(205, 133, 63),
+        "pink" => rgb(255, 192, 203),
+        "plum" => rgb(221, 160, 221),
+        "powderblue" => rgb(176, 224, 230),
+        "rebeccapurple" => rgb(102, 51, 153),
+        "rosybrown" => rgb(188, 143, 143),
+        "royalblue" => rgb(65, 105, 225),
+        "saddlebrown" => rgb(139, 69, 19),
+        "salmon" => rgb(250, 128, 114),
+        "sandybrown" => rgb(244, 164, 96),
+        "seagreen" => rgb(46, 139, 87),
+        "seashell" => rgb(255, 245, 238),
+        "sienna" => rgb(160, 82, 45),
+        "skyblue" => rgb(135, 206, 235),
+        "slateblue" => rgb(106, 90, 205),
+        "slategray" => rgb(112, 128, 144),
+        "slategrey" => rgb(112, 128, 144),
+        "snow" => rgb(255, 250, 250),
+        "springgreen" => rgb(0, 255, 127),
+        "steelblue" => rgb(70, 130, 180),
+        "tan" => rgb(210, 180, 140),
+        "thistle" => rgb(216, 191, 216),
+        "tomato" => rgb(255, 99, 71),
+        "turquoise" => rgb(64, 224, 208),
+        "violet" => rgb(238, 130, 238),
+        "wheat" => rgb(245, 222, 179),
+        "whitesmoke" => rgb(245, 245, 245),
+        "yellowgreen" => rgb(154, 205, 50),
 
-        "transparent" => Ok(Color::RGBA(RGBA { red: 0., green: 0., blue: 0., alpha: 0. })),
+        "transparent" => rgba(0, 0, 0, 0),
         "currentcolor" => Ok(Color::CurrentColor),
         _ => Err(())
     }
 }
 
 
 #[inline]
 fn from_hex(c: u8) -> Result<u8, ()> {
@@ -304,115 +338,123 @@ fn from_hex(c: u8) -> Result<u8, ()> {
 }
 
 
 #[inline]
 fn parse_color_hash(value: &str) -> Result<Color, ()> {
     let value = value.as_bytes();
     match value.len() {
         8 => rgba(
-            (try!(from_hex(value[0])) * 16 + try!(from_hex(value[1]))) as f32,
-            (try!(from_hex(value[2])) * 16 + try!(from_hex(value[3]))) as f32,
-            (try!(from_hex(value[4])) * 16 + try!(from_hex(value[5]))) as f32,
-            (try!(from_hex(value[6])) * 16 + try!(from_hex(value[7]))) as f32,
+            try!(from_hex(value[0])) * 16 + try!(from_hex(value[1])),
+            try!(from_hex(value[2])) * 16 + try!(from_hex(value[3])),
+            try!(from_hex(value[4])) * 16 + try!(from_hex(value[5])),
+            try!(from_hex(value[6])) * 16 + try!(from_hex(value[7])),
         ),
         6 => rgb(
-            (try!(from_hex(value[0])) * 16 + try!(from_hex(value[1]))) as f32,
-            (try!(from_hex(value[2])) * 16 + try!(from_hex(value[3]))) as f32,
-            (try!(from_hex(value[4])) * 16 + try!(from_hex(value[5]))) as f32,
+            try!(from_hex(value[0])) * 16 + try!(from_hex(value[1])),
+            try!(from_hex(value[2])) * 16 + try!(from_hex(value[3])),
+            try!(from_hex(value[4])) * 16 + try!(from_hex(value[5])),
         ),
         4 => rgba(
-            (try!(from_hex(value[0])) * 17) as f32,
-            (try!(from_hex(value[1])) * 17) as f32,
-            (try!(from_hex(value[2])) * 17) as f32,
-            (try!(from_hex(value[3])) * 17) as f32,
+            try!(from_hex(value[0])) * 17,
+            try!(from_hex(value[1])) * 17,
+            try!(from_hex(value[2])) * 17,
+            try!(from_hex(value[3])) * 17,
         ),
         3 => rgb(
-            (try!(from_hex(value[0])) * 17) as f32,
-            (try!(from_hex(value[1])) * 17) as f32,
-            (try!(from_hex(value[2])) * 17) as f32,
+            try!(from_hex(value[0])) * 17,
+            try!(from_hex(value[1])) * 17,
+            try!(from_hex(value[2])) * 17,
         ),
         _ => Err(())
     }
 }
 
 
+fn clamp_i32(val: i32) -> u8 {
+    cmp::min(cmp::max(0, val), 255) as u8
+}
+
+fn clamp_f32(val: f32) -> u8 {
+    // Scale by 256, not 255, so that each of the 256 u8 values has an equal range
+    // of f32 values mapping to it. Floor before clamping.
+    //
+    // Clamping to 256 and flooring after would let 1.0 map to 256, and
+    // `256.0_f32 as u8` is undefined behavior:
+    //
+    // https://github.com/rust-lang/rust/issues/10184
+    (val * 256.).floor().max(0.).min(255.) as u8
+}
+
 #[inline]
 fn parse_color_function(name: &str, arguments: &mut Parser) -> Result<Color, ()> {
     let (is_rgb, has_alpha) = match_ignore_ascii_case! { name,
         "rgba" => (true, true),
         "rgb" => (true, false),
         "hsl" => (false, false),
         "hsla" => (false, true),
         _ => return Err(())
     };
 
-    fn clamp(val: f32) -> f32 {
-        val.max(0.).min(1.)
-    }
-
-    let mut red: f32;
-    let mut green: f32;
-    let mut blue: f32;
+    let red: u8;
+    let green: u8;
+    let blue: u8;
     if is_rgb {
         // Either integers or percentages, but all the same type.
+        // https://drafts.csswg.org/css-color/#rgb-functions
         match try!(arguments.next()) {
-            Token::Number(ref v) if v.int_value.is_some() => {
-                red = v.value / 255.;
+            Token::Number(NumericValue { int_value: Some(v), .. }) => {
+                red = clamp_i32(v);
                 try!(arguments.expect_comma());
-                green = try!(arguments.expect_integer()) as f32 / 255.;
+                green = clamp_i32(try!(arguments.expect_integer()));
                 try!(arguments.expect_comma());
-                blue = try!(arguments.expect_integer()) as f32 / 255.;
+                blue = clamp_i32(try!(arguments.expect_integer()));
             }
             Token::Percentage(ref v) => {
-                red = v.unit_value;
+                red = clamp_f32(v.unit_value);
                 try!(arguments.expect_comma());
-                green = try!(arguments.expect_percentage());
+                green = clamp_f32(try!(arguments.expect_percentage()));
                 try!(arguments.expect_comma());
-                blue = try!(arguments.expect_percentage());
+                blue = clamp_f32(try!(arguments.expect_percentage()));
             }
             _ => return Err(())
         };
-        // The spec says to clamp to the device gamut which may be wider than 0% ... 100%,
-        // but moz2d doesn’t seem to have any support for this, so let’s not bother.
-        // https://drafts.csswg.org/css-color/#rgb-functions
-        // https://github.com/servo/rust-cssparser/issues/76
-        red = clamp(red);
-        green = clamp(green);
-        blue = clamp(blue);
     } else {
-        let hue = try!(arguments.expect_number()) / 360.;
-        let hue = hue - hue.floor();
+        let hue_degrees = try!(arguments.expect_number());
+        // Subtract an integer before rounding, to avoid some rounding errors:
+        let hue_normalized_degrees = hue_degrees - 360. * (hue_degrees / 360.).floor();
+        let hue = hue_normalized_degrees / 360.;
         // Saturation and lightness are clamped to 0% ... 100%
-        // regardless of device gamut:
         // https://drafts.csswg.org/css-color/#the-hsl-notation
         try!(arguments.expect_comma());
-        let saturation = clamp(try!(arguments.expect_percentage()));
+        let saturation = try!(arguments.expect_percentage()).max(0.).min(1.);
         try!(arguments.expect_comma());
-        let lightness = clamp(try!(arguments.expect_percentage()));
+        let lightness = try!(arguments.expect_percentage()).max(0.).min(1.);
 
         // https://drafts.csswg.org/css-color/#hsl-color
-        fn hue_to_rgb(m1: f32, m2: f32, mut h: f32) -> f32 {
-            if h < 0. { h += 1. }
-            if h > 1. { h -= 1. }
+        // except with h pre-multiplied by 3, to avoid some rounding errors.
+        fn hue_to_rgb(m1: f32, m2: f32, mut h3: f32) -> f32 {
+            if h3 < 0. { h3 += 3. }
+            if h3 > 3. { h3 -= 3. }
 
-            if h * 6. < 1. { m1 + (m2 - m1) * h * 6. }
-            else if h * 2. < 1. { m2 }
-            else if h * 3. < 2. { m1 + (m2 - m1) * (2. / 3. - h) * 6. }
+            if h3 * 2. < 1. { m1 + (m2 - m1) * h3 * 2. }
+            else if h3 * 2. < 3. { m2 }
+            else if h3 < 2. { m1 + (m2 - m1) * (2. - h3) * 2. }
             else { m1 }
         }
         let m2 = if lightness <= 0.5 { lightness * (saturation + 1.) }
                  else { lightness + saturation - lightness * saturation };
         let m1 = lightness * 2. - m2;
-        red = hue_to_rgb(m1, m2, hue + 1. / 3.);
-        green = hue_to_rgb(m1, m2, hue);
-        blue = hue_to_rgb(m1, m2, hue - 1. / 3.);
+        let hue_times_3 = hue * 3.;
+        red = clamp_f32(hue_to_rgb(m1, m2, hue_times_3 + 1.));
+        green = clamp_f32(hue_to_rgb(m1, m2, hue_times_3));
+        blue = clamp_f32(hue_to_rgb(m1, m2, hue_times_3 - 1.));
     }
 
     let alpha = if has_alpha {
         try!(arguments.expect_comma());
-        clamp(try!(arguments.expect_number()))
+        clamp_f32(try!(arguments.expect_number()))
     } else {
-        1.
+        255
     };
     try!(arguments.expect_exhausted());
-    Ok(Color::RGBA(RGBA { red: red, green: green, blue: blue, alpha: alpha }))
+    rgba(red, green, blue, alpha)
 }
--- a/third_party/rust/cssparser/src/css-parsing-tests/README.rst
+++ b/third_party/rust/cssparser/src/css-parsing-tests/README.rst
@@ -1,15 +1,15 @@
 CSS parsing tests
 #################
 
 This repository contains implementation-independent test for CSS parsers,
 based on the 2013 draft of the `CSS Syntax Level 3`_ specification.
 
-.. _CSS Syntax Level 3: http://dev.w3.org/csswg/css-syntax-3/
+.. _CSS Syntax Level 3: https://drafts.csswg.org/css-syntax-3/
 
 The upstream repository for these tests is at
 https://github.com/SimonSapin/css-parsing-tests
 
 
 Projects using this
 ===================
 
@@ -46,61 +46,61 @@ CSS Syntax specification describes a num
 Each ``.json`` file in this repository corresponds to such a function.
 The files are encoded as UTF-8
 and each contain a JSON array with an even number of items,
 where each pair of items is one function input
 associated with the expected result.
 
 ``component_value_list.json``
     Tests `Parse a list of component values
-    <http://dev.w3.org/csswg/css-syntax-3/#parse-a-list-of-component-values>`_.
+    <https://drafts.csswg.org/css-syntax-3/#parse-a-list-of-component-values>`_.
     The Unicode input is represented by a JSON string,
     the output as an array of `component values`_ as described below.
 
 ``component_value_list.json``
     Tests `Parse a component value
-    <http://dev.w3.org/csswg/css-syntax-3/#parse-a-component-value>`_.
+    <https://drafts.csswg.org/css-syntax-3/#parse-a-component-value>`_.
     The Unicode input is represented by a JSON string,
     the output as a `component value`_.
 
 ``declaration_list.json``
     Tests `Parse a list of declarations
-    <http://dev.w3.org/csswg/css-syntax-3/#parse-a-list-of-declarations>`_.
+    <https://drafts.csswg.org/css-syntax-3/#parse-a-list-of-declarations>`_.
     The Unicode input is represented by a JSON string,
     the output as an array of declarations_ and at-rules_.
 
 ``one_declaration.json``
     Tests `Parse a declaration
-    <http://dev.w3.org/csswg/css-syntax-3/#parse-a-declaration>`_.
+    <https://drafts.csswg.org/css-syntax-3/#parse-a-declaration>`_.
     The Unicode input is represented by a JSON string,
     the output as a declaration_.
 
 ``one_rule.json``
     Tests `Parse a rule
-    <http://dev.w3.org/csswg/css-syntax-3/#parse-a-rule>`_.
+    <https://drafts.csswg.org/css-syntax-3/#parse-a-rule>`_.
     The Unicode input is represented by a JSON string,
     the output as a `qualified rule`_ or at-rule_.
 
 ``rule_list.json``
     Tests `Parse a list of rules
-    <http://dev.w3.org/csswg/css-syntax-3/#parse-a-list-of-rules>`_.
+    <https://drafts.csswg.org/css-syntax-3/#parse-a-list-of-rules>`_.
     The Unicode input is represented by a JSON string,
     the output as a list of `qualified rules`_ or at-rules_.
 
 ``stylesheet.json``
     Tests `Parse a stylesheet
-    <http://dev.w3.org/csswg/css-syntax-3/#parse-a-stylesheet>`_.
+    <https://drafts.csswg.org/css-syntax-3/#parse-a-stylesheet>`_.
     The Unicode input is represented by a JSON string,
     the output as a list of `qualified rules`_ or at-rules_.
 
 ``stylesheet_bytes.json``
     Tests `Parse a stylesheet
-    <http://dev.w3.org/csswg/css-syntax-3/#parse-a-stylesheet>`_
+    <https://drafts.csswg.org/css-syntax-3/#parse-a-stylesheet>`_
     together with `The input byte stream
-    <http://dev.w3.org/csswg/css-syntax/#input-byte-stream>`_.
+    <https://drafts.csswg.org/css-syntax-3/#input-byte-stream>`_.
     The input is represented as a JSON object containing:
 
     * A required ``css_bytes``, the input byte string,
       represented as a JSON string where code points U+0000 to U+00FF
       represent bytes of the same value.
     * An optional ``protocol_encoding``,
       a protocol encoding label as a JSON string, or null.
     * An optional ``environment_encoding``,
@@ -127,26 +127,33 @@ associated with the expected result.
 
 ``color3_keywords.json``
     Same as ``color3.json``,
     except that the values for the Red, Green and Blue channel
     are between 0 and 255.
     This file is generated by the ``make_color3_keywords.py`` Python script.
 
 ``An+B.json``
-    Tests the `An+B <http://dev.w3.org/csswg/css-syntax/#the-anb-type>`_
+    Tests the `An+B <https://drafts.csswg.org/css-syntax-3/#the-anb-type>`_
     syntax defined in CSS Syntax Level 3.
-    This `differs <http://dev.w3.org/csswg/css-syntax/#changes>`_ from the
+    This `differs <https://drafts.csswg.org/css-syntax/#changes>`_ from the
     `nth grammar rule <http://www.w3.org/TR/css3-selectors/#nth-child-pseudo>`_
     in Selectors Level 3 only in that
-    ``-`` charecters and digits can be escaped in some cases.
+    ``-`` characters and digits can be escaped in some cases.
     The Unicode input is represented by a JSON string,
     the output as null for invalid syntax,
     or an array of two integers ``[A, B]``.
 
+``urange.json``
+    Tests the `urange <https://drafts.csswg.org/css-syntax-3/#urange>`_
+    syntax defined in CSS Syntax Level 3.
+    The Unicode input is represented by a JSON string,
+    the output as null for invalid syntax,
+    or an array of two integers ``[start, end]``.
+
 
 Result representation
 =====================
 
 AST nodes (the results of parsing) are represented in JSON as follow.
 This representation was chosen to be compact
 (and thus less annoying to write by hand)
 while staying unambiguous.
@@ -223,20 +230,16 @@ Component values
     Array of length 4: the string ``"percentage"``, the representation as a string,
     the value as a number, and the type as the string ``"integer"`` or ``"number"``.
 
 <dimension>
     Array of length 4: the string ``"dimension"``, the representation as a string,
     the value as a number, the type as the string ``"integer"`` or ``"number"``,
     and the unit as a string.
 
-<unicode-range>
-    Array of length 3: the string ``"unicode-range"``,
-    followed by the *start* and *end* integers as two numbers.
-
 <include-match>
     The string ``"~="``.
 
 <dash-match>
     The string ``"|="``.
 
 <prefix-match>
     The string ``"^="``.
--- a/third_party/rust/cssparser/src/css-parsing-tests/color3.json
+++ b/third_party/rust/cssparser/src/css-parsing-tests/color3.json
@@ -6,141 +6,141 @@
 "/**/transparent", [0, 0, 0, 0],
 "transparent", [0, 0, 0, 0],
 " transparent\n", [0, 0, 0, 0],
 "TransParent", [0, 0, 0, 0],
 "currentColor", "currentColor",
 "CURRENTcolor", "currentColor",
 "current-Color", null,
 
-"black", [0, 0, 0, 1],
-"white", [1, 1, 1, 1],
-"fuchsia", [1, 0, 1, 1],
-"cyan", [0, 1, 1, 1],
-"CyAn", [0, 1, 1, 1],
+"black", [0, 0, 0, 255],
+"white", [255, 255, 255, 255],
+"fuchsia", [255, 0, 255, 255],
+"cyan", [0, 255, 255, 255],
+"CyAn", [0, 255, 255, 255],
 
 "#", null,
 "#f", null,
 "#ff", null,
-"#fff", [1, 1, 1, 1],
+"#fff", [255, 255, 255, 255],
 "#ffg", null,
-"#ffff", [1, 1, 1, 1],
+"#ffff", [255, 255, 255, 255],
 "#fffg", null,
 "#fffff", null,
-"#ffffff", [1, 1, 1, 1],
+"#ffffff", [255, 255, 255, 255],
 "#fffffg", null,
 "#fffffff", null,
-"#ffffffff", [1, 1, 1, 1],
+"#ffffffff", [255, 255, 255, 255],
 "#fffffffg", null,
 "#fffffffff", null,
 
-"#FFCc99", [1, 0.8, 0.6, 1],
-"#369", [0.2, 0.4, 0.6, 1],
+"#FFCc99", [255, 204, 153, 255],
+"#369", [51, 102, 153, 255],
 
  "#ffé", null, "#fffffé", null,
 
-"rgb(00, 51, 102)", [0, 0.2, 0.4, 1],
-"r\\gb(00, 51, 102)", [0, 0.2, 0.4, 1],
-"r\\67 b(00, 51, 102)", [0, 0.2, 0.4, 1],
-"RGB(153, 204, 255)", [0.6, 0.8, 1, 1],
-"rgB(0, 0, 0)", [0, 0, 0, 1],
-"rgB(0, 51, 255)", [0, 0.2, 1, 1],
-"rgb(0,51,255)", [0, 0.2, 1, 1],
-"rgb(0\t,  51 ,255)", [0, 0.2, 1, 1],
-"rgb(/* R */0, /* G */51, /* B */255)", [0, 0.2, 1, 1],
-"rgb(-51, 306, 0)", [0, 1, 0, 1],
+"rgb(00, 51, 102)", [0, 51, 102, 255],
+"r\\gb(00, 51, 102)", [0, 51, 102, 255],
+"r\\67 b(00, 51, 102)", [0, 51, 102, 255],
+"RGB(153, 204,255)", [153, 204, 255, 255],
+"rgB(0, 0, 0)", [0, 0, 0, 255],
+"rgB(0, 51,255)", [0, 51, 255, 255],
+"rgb(0,51,255)", [0, 51, 255, 255],
+"rgb(0\t, 51 ,255)", [0, 51, 255, 255],
+"rgb(/* R */0, /* G */51, /* B */255)", [0, 51, 255, 255],
+"rgb(-51, 306, 0)", [0, 255, 0, 255],
 
-"rgb(42%, 3%, 50%)", [0.42, 0.03, 0.5, 1],
-"RGB(100%, 100%, 100%)", [1, 1, 1, 1],
-"rgB(0%, 0%, 0%)", [0, 0, 0, 1],
-"rgB(10%, 20%, 30%)", [0.1, 0.2, 0.3, 1],
-"rgb(10%,20%,30%)", [0.1, 0.2, 0.3, 1],
-"rgb(10%\t,  20% ,30%)", [0.1, 0.2, 0.3, 1],
-"rgb(/* R */ 10%, /* G */ 20%, /* B */ 30%)", [0.1, 0.2, 0.3, 1],
-"rgb(-12%, 110%, 1400%)", [0, 1, 1, 1],
+"rgb(12.5%, 25%, 50%)", [32, 64, 128, 255],
+"RGB(100%, 100%, 100%)", [255, 255, 255, 255],
+"rgB(0%, 0%, 0%)", [0, 0, 0, 255],
+"rgB(37.5%, 75%, 0%)", [96, 192, 0, 255],
+"rgb(37.5%,75%,0%)", [96, 192, 0, 255],
+"rgb(37.5%\t, 75%, 0%)", [96, 192, 0, 255],
+"rgb(/* R */ 37.5%, /* G */ 75%,  /* B */ 0%)", [96, 192, 0, 255],
+"rgb(-12%, 110%, 1400%)", [0, 255, 255, 255],
 
 "rgb(10%, 50%, 0)", null,
 "rgb(255, 50%, 0%)", null,
 "rgb(0, 0 0)", null,
 "rgb(0, 0, 0deg)", null,
 "rgb(0, 0, light)", null,
 "rgb()", null,
 "rgb(0)", null,
 "rgb(0, 0)", null,
 "rgb(0, 0, 0, 0)", null,
 "rgb(0%)", null,
 "rgb(0%, 0%)", null,
 "rgb(0%, 0%, 0%, 0%)", null,
 "rgb(0%, 0%, 0%, 0)", null,
 
 "rgba(0, 0, 0, 0)", [0, 0, 0, 0],
-"rgba(204, 0, 102, 0.3)", [0.8, 0, 0.4, 0.3],
-"RGBA(255, 255, 255, 0)", [1, 1, 1, 0],
-"rgBA(0, 51, 255, 1)", [0, 0.2, 1, 1],
-"rgba(0, 51, 255, 1.1)", [0, 0.2, 1, 1],
-"rgba(0, 51, 255, 37)", [0, 0.2, 1, 1],
-"rgba(0, 51, 255, 0.42)", [0, 0.2, 1, 0.42],
-"rgba(0, 51, 255, 0)", [0, 0.2, 1, 0],
-"rgba(0, 51, 255, -0.1)", [0, 0.2, 1, 0],
-"rgba(0, 51, 255, -139)", [0, 0.2, 1, 0],
+"rgba(204, 0, 102, 0.25)", [204, 0, 102, 64],
+"RGBA(255,255,255, 0)", [255, 255, 255, 0],
+"rgBA(0, 51,255, 1)", [0, 51, 255, 255],
+"rgba(0, 51,255, 1.1)", [0, 51, 255, 255],
+"rgba(0, 51,255, 37)", [0, 51, 255, 255],
+"rgba(0, 51,255, 0.5)", [0, 51, 255, 128],
+"rgba(0, 51,255, 0)", [0, 51, 255, 0],
+"rgba(0, 51,255, -0.1)", [0, 51, 255, 0],
+"rgba(0, 51,255, -139)", [0, 51, 255, 0],
 
-"rgba(42%, 3%, 50%, 0.3)", [0.42, 0.03, 0.5, 0.3],
-"RGBA(100%, 100%, 100%, 0)", [1, 1, 1, 0],
-"rgBA(0%, 20%, 100%, 1)", [0, 0.2, 1, 1],
-"rgba(0%, 20%, 100%, 1.1)", [0, 0.2, 1, 1],
-"rgba(0%, 20%, 100%, 37)", [0, 0.2, 1, 1],
-"rgba(0%, 20%, 100%, 0.42)", [0, 0.2, 1, 0.42],
-"rgba(0%, 20%, 100%, 0)", [0, 0.2, 1, 0],
-"rgba(0%, 20%, 100%, -0.1)", [0, 0.2, 1, 0],
-"rgba(0%, 20%, 100%, -139)", [0, 0.2, 1, 0],
+"rgba(12.5%, 25%, 50%, 0.25)", [32, 64, 128, 64],
+"RGBA(100%, 100%, 100%, 0)", [255, 255, 255, 0],
+"rgBA(0%, 20%, 100%, 1)", [0, 51, 255, 255],
+"rgba(0%, 20%, 100%, 1.1)", [0, 51, 255, 255],
+"rgba(0%, 20%, 100%, 37)", [0, 51, 255, 255],
+"rgba(0%, 20%, 100%, 0.25)", [0, 51, 255, 64],
+"rgba(0%, 20%, 100%, 0)", [0, 51, 255, 0],
+"rgba(0%, 20%, 100%, -0.1)", [0, 51, 255, 0],
+"rgba(0%, 20%, 100%, -139)", [0, 51, 255, 0],
 
-"rgba(255, 255, 255, 0%)", null,
+"rgba(255,255,255, 0%)", null,
 "rgba(10%, 50%, 0, 1)", null,
 "rgba(255, 50%, 0%, 1)", null,
 "rgba(0, 0, 0 0)", null,
 "rgba(0, 0, 0, 0deg)", null,
 "rgba(0, 0, 0, light)", null,
 "rgba()", null,
 "rgba(0)", null,
 "rgba(0, 0, 0)", null,
 "rgba(0, 0, 0, 0, 0)", null,
 "rgba(0%)", null,
 "rgba(0%, 0%)", null,
 "rgba(0%, 0%, 0%)", null,
 "rgba(0%, 0%, 0%, 0%)", null,
 "rgba(0%, 0%, 0%, 0%, 0%)", null,
 
-"HSL(0, 0%, 0%)", [0, 0, 0, 1],
-"hsL(0, 100%, 50%)", [1, 0, 0, 1],
-"hsl(60, 100%, 37.5%)", [0.75, 0.75, 0, 1],
-"hsl(780, 100%, 37.5%)", [0.75, 0.75, 0, 1],
-"hsl(-300, 100%, 37.5%)", [0.75, 0.75, 0, 1],
-"hsl(300, 50%, 50%)", [0.75, 0.25, 0.75, 1],
+"HSL(0, 0%, 0%)", [0, 0, 0, 255],
+"hsL(0, 100%, 50%)", [255, 0, 0, 255],
+"hsl(60, 100%, 37.5%)", [192, 192, 0, 255],
+"hsl(780, 100%, 37.5%)", [192, 192, 0, 255],
+"hsl(-300, 100%, 37.5%)", [192, 192, 0, 255],
+"hsl(300, 50%, 50%)", [192, 64, 192, 255],
 
 "hsl(10, 50%, 0)", null,
 "hsl(50%, 50%, 0%)", null,
 "hsl(0, 0% 0%)", null,
 "hsl(30deg, 100%, 100%)", null,
 "hsl(0, 0%, light)", null,
 "hsl()", null,
 "hsl(0)", null,
 "hsl(0, 0%)", null,
 "hsl(0, 0%, 0%, 0%)", null,
 
-"HSLA(-300, 100%, 37.5%, 1)", [0.75, 0.75, 0, 1],
-"hsLA(-300, 100%, 37.5%, 12)", [0.75, 0.75, 0, 1],
-"hsla(-300, 100%, 37.5%, 0.2)", [0.75, 0.75, 0, 0.2],
-"hsla(-300, 100%, 37.5%, 0)", [0.75, 0.75, 0, 0],
-"hsla(-300, 100%, 37.5%, -3)", [0.75, 0.75, 0, 0],
+"HSLA(-300, 100%, 37.5%, 1)", [192, 192, 0, 255],
+"hsLA(-300, 100%, 37.5%, 12)", [192, 192, 0, 255],
+"hsla(-300, 100%, 37.5%, 0.2)", [192, 192, 0, 51],
+"hsla(-300, 100%, 37.5%, 0)", [192, 192, 0, 0],
+"hsla(-300, 100%, 37.5%, -3)", [192, 192, 0, 0],
 
 "hsla(10, 50%, 0, 1)", null,
 "hsla(50%, 50%, 0%, 1)", null,
 "hsla(0, 0% 0%, 1)", null,
 "hsla(30deg, 100%, 100%, 1)", null,
 "hsla(0, 0%, light, 1)", null,
 "hsla()", null,
 "hsla(0)", null,
 "hsla(0, 0%)", null,
 "hsla(0, 0%, 0%, 50%)", null,
-"hsla(0, 0%, 0%, 1, 0%)", null,
+"hsla(0, 0%, 0%, 255, 0%)", null,
 
 "cmyk(0, 0, 0, 0)", null
 ]
--- a/third_party/rust/cssparser/src/css-parsing-tests/color3_hsl.json
+++ b/third_party/rust/cssparser/src/css-parsing-tests/color3_hsl.json
@@ -1,3890 +1,3890 @@
 [
-"hsl(0, 0%, 0%)", [0, 0, 0, 1],
-"hsl(30, 0%, 0%)", [0, 0, 0, 1],
-"hsl(60, 0%, 0%)", [0, 0, 0, 1],
-"hsl(90, 0%, 0%)", [0, 0, 0, 1],
-"hsl(120, 0%, 0%)", [0, 0, 0, 1],
-"hsl(150, 0%, 0%)", [0, 0, 0, 1],
-"hsl(180, 0%, 0%)", [0, 0, 0, 1],
-"hsl(210, 0%, 0%)", [0, 0, 0, 1],
-"hsl(240, 0%, 0%)", [0, 0, 0, 1],
-"hsl(270, 0%, 0%)", [0, 0, 0, 1],
-"hsl(300, 0%, 0%)", [0, 0, 0, 1],
-"hsl(330, 0%, 0%)", [0, 0, 0, 1],
-"hsl(0, 12.5%, 0%)", [0, 0, 0, 1],
-"hsl(30, 12.5%, 0%)", [0, 0, 0, 1],
-"hsl(60, 12.5%, 0%)", [0, 0, 0, 1],
-"hsl(90, 12.5%, 0%)", [0, 0, 0, 1],
-"hsl(120, 12.5%, 0%)", [0, 0, 0, 1],
-"hsl(150, 12.5%, 0%)", [0, 0, 0, 1],
-"hsl(180, 12.5%, 0%)", [0, 0, 0, 1],
-"hsl(210, 12.5%, 0%)", [0, 0, 0, 1],
-"hsl(240, 12.5%, 0%)", [0, 0, 0, 1],
-"hsl(270, 12.5%, 0%)", [0, 0, 0, 1],
-"hsl(300, 12.5%, 0%)", [0, 0, 0, 1],
-"hsl(330, 12.5%, 0%)", [0, 0, 0, 1],
-"hsl(0, 25%, 0%)", [0, 0, 0, 1],
-"hsl(30, 25%, 0%)", [0, 0, 0, 1],
-"hsl(60, 25%, 0%)", [0, 0, 0, 1],
-"hsl(90, 25%, 0%)", [0, 0, 0, 1],
-"hsl(120, 25%, 0%)", [0, 0, 0, 1],
-"hsl(150, 25%, 0%)", [0, 0, 0, 1],
-"hsl(180, 25%, 0%)", [0, 0, 0, 1],
-"hsl(210, 25%, 0%)", [0, 0, 0, 1],
-"hsl(240, 25%, 0%)", [0, 0, 0, 1],
-"hsl(270, 25%, 0%)", [0, 0, 0, 1],
-"hsl(300, 25%, 0%)", [0, 0, 0, 1],
-"hsl(330, 25%, 0%)", [0, 0, 0, 1],
-"hsl(0, 37.5%, 0%)", [0, 0, 0, 1],
-"hsl(30, 37.5%, 0%)", [0, 0, 0, 1],
-"hsl(60, 37.5%, 0%)", [0, 0, 0, 1],
-"hsl(90, 37.5%, 0%)", [0, 0, 0, 1],
-"hsl(120, 37.5%, 0%)", [0, 0, 0, 1],
-"hsl(150, 37.5%, 0%)", [0, 0, 0, 1],
-"hsl(180, 37.5%, 0%)", [0, 0, 0, 1],
-"hsl(210, 37.5%, 0%)", [0, 0, 0, 1],
-"hsl(240, 37.5%, 0%)", [0, 0, 0, 1],
-"hsl(270, 37.5%, 0%)", [0, 0, 0, 1],
-"hsl(300, 37.5%, 0%)", [0, 0, 0, 1],
-"hsl(330, 37.5%, 0%)", [0, 0, 0, 1],
-"hsl(0, 50%, 0%)", [0, 0, 0, 1],
-"hsl(30, 50%, 0%)", [0, 0, 0, 1],
-"hsl(60, 50%, 0%)", [0, 0, 0, 1],