diff --git a/Cargo.lock b/Cargo.lock index fa908ea9d7..445c167891 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "aho-corasick" -version = "0.7.18" +version = "0.7.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" dependencies = [ "memchr", ] @@ -61,8 +61,7 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "cexpr" version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +source = "git+https://github.com/reitermarkus/rust-cexpr?branch=cast-expr#1a4f02bc375c3aa4b58c6aac55c7244b70fa702f" dependencies = [ "nom", ] @@ -86,9 +85,9 @@ dependencies = [ [[package]] name = "clap" -version = "3.2.12" +version = "3.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab8b79fe3946ceb4a0b1c080b4018992b8d27e9ff363644c1c9b6387c854614d" +checksum = "23b71c3ce99b7611011217b366d923f1d0a7e07a92bb2dbf1e84508c673ca3bd" dependencies = [ "atty", "bitflags", @@ -110,15 +109,15 @@ dependencies = [ [[package]] name = "diff" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e25ea47919b1560c4e3b7fe0aaab9becf5b84a10325ddf7db0f0ba5e1026499" +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" [[package]] name = "either" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" [[package]] name = "env_logger" @@ -134,14 +133,12 @@ dependencies = [ ] [[package]] -name = "getrandom" -version = "0.2.3" +name = "fastrand" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" dependencies = [ - "cfg-if", - "libc", - "wasi", + "instant", ] [[package]] @@ -152,9 +149,9 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] name = "hashbrown" -version = "0.12.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "607c8a29735385251a339424dd462993c0fed8fa09d378f259377df08c126022" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hermit-abi" @@ -181,6 +178,15 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -195,15 +201,15 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.126" +version = "0.2.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" +checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" [[package]] name = "libloading" -version = "0.7.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f84d96438c15fcd6c3f244c8fce01d1e2b9c6b5623e9c711dc9286d8fc92d6a" +checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd" dependencies = [ "cfg-if", "winapi", @@ -211,9 +217,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.14" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ "cfg-if", ] @@ -226,26 +232,31 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "minimal-lexical" -version = "0.1.4" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c64630dcdd71f1a64c435f54885086a0de5d6a12d104d69b165fb7d5286d677" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "nom" -version = "7.0.0" +version = "7.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffd9d26838a953b4af82cbeb9f1592c6798916983959be223a7124e992742c1" +checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" dependencies = [ "memchr", "minimal-lexical", - "version_check", ] +[[package]] +name = "once_cell" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0" + [[package]] name = "os_str_bytes" -version = "6.2.0" +version = "6.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "648001efe5d5c0102d8cea768e348da85d90af8ba91f0bea908f157951493cd4" +checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff" [[package]] name = "peeking_take_while" @@ -253,12 +264,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" -[[package]] -name = "ppv-lite86" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" - [[package]] name = "proc-macro2" version = "1.0.43" @@ -270,67 +275,27 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.9" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" dependencies = [ "proc-macro2", ] -[[package]] -name = "rand" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", - "rand_hc", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rand_hc" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" -dependencies = [ - "rand_core", -] - [[package]] name = "redox_syscall" -version = "0.2.9" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ab49abadf3f9e1c4bc499e8845e152ad87d2ad2d30371841171169e9d75feee" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ "bitflags", ] [[package]] name = "regex" -version = "1.5.5" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" +checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" dependencies = [ "aho-corasick", "memchr", @@ -339,9 +304,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.25" +version = "0.6.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" +checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" [[package]] name = "remove_dir_all" @@ -360,9 +325,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "shlex" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42a568c8f2cd051a4d283bd6eb0343ac214c1b0f1ac19f93e1175b2dee38c73d" +checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" [[package]] name = "strsim" @@ -383,13 +348,13 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.2.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" dependencies = [ "cfg-if", + "fastrand", "libc", - "rand", "redox_syscall", "remove_dir_all", "winapi", @@ -416,27 +381,15 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf" -[[package]] -name = "version_check" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" - -[[package]] -name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - [[package]] name = "which" -version = "4.2.2" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea187a8ef279bc014ec368c27a920da2024d2a711109bfbe3440585d5cf27ad9" +checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b" dependencies = [ "either", - "lazy_static", "libc", + "once_cell", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 311110b3ec..b22be0e8d0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -86,3 +86,7 @@ testing_only_docs = [] testing_only_extra_assertions = [] testing_only_libclang_9 = [] testing_only_libclang_5 = [] + +[patch.crates-io] +cexpr = { git = "https://github.com/reitermarkus/rust-cexpr", branch = "cast-expr" } +# cexpr = { path = "./rust-cexpr" } diff --git a/bindgen-integration/Cargo.toml b/bindgen-integration/Cargo.toml index 733fba58db..5c33781f7f 100644 --- a/bindgen-integration/Cargo.toml +++ b/bindgen-integration/Cargo.toml @@ -18,3 +18,6 @@ testing_only_docs = ["bindgen/testing_only_docs"] testing_only_extra_assertions = ["bindgen/testing_only_extra_assertions"] testing_only_libclang_9 = ["bindgen/testing_only_libclang_9"] testing_only_libclang_5 = ["bindgen/testing_only_libclang_5"] + +[patch.crates-io] +cexpr = { git = "https://github.com/reitermarkus/rust-cexpr", branch = "cast-expr" } diff --git a/minimal.h b/minimal.h new file mode 100644 index 0000000000..bc192199c4 --- /dev/null +++ b/minimal.h @@ -0,0 +1,8 @@ +#include +#include + +#define MY_USHORT (unsigned short) ULONG_MAX + +typedef unsigned long TickType_t; +#define portMAX_DELAY (TickType_t) ULONG_MAX +const TickType_t __portMAX_DELAY = portMAX_DELAY; diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index ca4cbf23ac..0cf33f8065 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -630,7 +630,18 @@ impl CodeGenerator for Var { attrs.push(attributes::doc(comment)); } - let ty = self.ty().to_rust_ty_or_opaque(ctx, &()); + let var_ty = if let Some(var_ty) = self.ty(ctx) { + var_ty + } else { + // FIXME: Parse/output macro variables as the last step when all types are known. + warn!( + "Failed to determine type for macro variable {}.", + canonical_name + ); + return; + }; + + let ty = var_ty.to_rust_ty_or_opaque(ctx, &()); if let Some(val) = self.val() { match *val { @@ -641,8 +652,7 @@ impl CodeGenerator for Var { }); } VarType::Int(val) => { - let int_kind = self - .ty() + let int_kind = var_ty .into_resolver() .through_type_aliases() .through_type_refs() diff --git a/src/ir/context.rs b/src/ir/context.rs index 7837e59491..4831375a71 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -354,6 +354,8 @@ pub struct BindgenContext { /// This needs to be an std::HashMap because the cexpr API requires it. parsed_macros: StdHashMap, cexpr::expr::EvalResult>, + wrapper_ids: StdHashMap, + /// A set of all the included filenames. deps: BTreeSet, @@ -555,6 +557,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" semantic_parents: Default::default(), currently_parsed_types: vec![], parsed_macros: Default::default(), + wrapper_ids: Default::default(), replacements: Default::default(), collected_typerefs: false, in_codegen: false, @@ -1919,7 +1922,10 @@ If you encounter an error missing from this list, please file an issue or a PR!" let layout = ty.fallible_layout(self).ok(); let location = ty.declaration().location(); let type_kind = TypeKind::ResolvedTypeRef(wrapped_id); - let ty = Type::new(Some(spelling), layout, type_kind, is_const); + + eprintln!("Building wrapper type {:?} ({:?})", spelling, wrapped_id); + + let ty = Type::new(Some(spelling.clone()), layout, type_kind, is_const); let item = Item::new( with_id, None, @@ -1929,7 +1935,15 @@ If you encounter an error missing from this list, please file an issue or a PR!" Some(location), ); self.add_builtin_item(item); - with_id.as_type_id_unchecked() + let type_id = with_id.as_type_id_unchecked(); + + self.wrapper_ids.insert(spelling.clone(), type_id); + + type_id + } + + pub(crate) fn wrapper_id_by_name(&self, name: &str) -> Option<&TypeId> { + self.wrapper_ids.get(name) } /// Returns the next item id to be used for an item. @@ -1988,6 +2002,9 @@ If you encounter an error missing from this list, please file an issue or a PR!" let is_const = ty.is_const(); let layout = ty.fallible_layout(self).ok(); let location = ty.declaration().location(); + + eprintln!("Building type {:?}", spelling); + let ty = Type::new(Some(spelling), layout, type_kind, is_const); let id = self.next_item_id(); let item = Item::new( diff --git a/src/ir/item.rs b/src/ir/item.rs index 3b15cd6ed6..d0684e2b9d 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -297,7 +297,9 @@ impl Trace for Item { tracer.visit(fun.signature().into()); } ItemKind::Var(ref var) => { - tracer.visit_kind(var.ty().into(), EdgeKind::VarType); + if let Some(ty) = var.ty(ctx) { + tracer.visit_kind(ty.into(), EdgeKind::VarType); + } } ItemKind::Module(_) => { // Module -> children edges are "weak", and we do not want to diff --git a/src/ir/var.rs b/src/ir/var.rs index e44d57afe4..17b48580ad 100644 --- a/src/ir/var.rs +++ b/src/ir/var.rs @@ -40,27 +40,42 @@ pub struct Var { /// The mangled name of the variable. mangled_name: Option, /// The type of the variable. - ty: TypeId, + ty: VarTypeId, /// The value of the variable, that needs to be suitable for `ty`. val: Option, /// Whether this variable is const. is_const: bool, } +/// Either a concrete `TypeId` or a type name which allows for lazy lookup later on. +#[derive(Debug)] +pub enum VarTypeId { + /// A known `TypeId`. + Concrete(TypeId), + /// A name for a type whose `TypeId` is may not yet be available. + Lazy(String), +} + +impl From for VarTypeId { + fn from(type_id: TypeId) -> Self { + Self::Concrete(type_id) + } +} + impl Var { /// Construct a new `Var`. pub fn new( name: String, mangled_name: Option, - ty: TypeId, + ty: impl Into, val: Option, is_const: bool, - ) -> Var { + ) -> Self { assert!(!name.is_empty()); - Var { + Self { name, mangled_name, - ty, + ty: ty.into(), val, is_const, } @@ -77,8 +92,23 @@ impl Var { } /// Get this variable's type. - pub fn ty(&self) -> TypeId { - self.ty + #[track_caller] + pub fn ty(&self, ctx: &BindgenContext) -> Option { + match self.ty { + VarTypeId::Concrete(type_id) => Some(type_id), + VarTypeId::Lazy(ref type_name) => { + let type_id = ctx.wrapper_id_by_name(type_name).or_else(|| { + ctx.wrapper_id_by_name(&format!("const {}", type_name)) + }); + + eprintln!( + "Looking for type_name '{}': {:?}", + type_name, type_id + ); + + type_id.cloned() + } + } } /// Get this variable's name. @@ -117,6 +147,25 @@ impl DotAttributes for Var { } } +fn default_limit_constant_type(name: &str, value: i64) -> Option { + Some(match name { + "SCHAR_MIN" | "SCHAR_MAX" => IntKind::SChar, + "CHAR_MIN" | "CHAR_MAX" => IntKind::Char { + is_signed: value < 0, + }, + "UCHAR_MIN" | "UCHAR_MAX" => IntKind::UChar, + "SHRT_MIN" | "SHRT_MAX" => IntKind::Short, + "USHRT_MIN" | "USHRT_MAX" => IntKind::UShort, + "INT_MIN" | "INT_MAX" => IntKind::Int, + "UINT_MIN" | "UINT_MAX" => IntKind::UInt, + "LONG_MIN" | "LONG_MAX" => IntKind::Long, + "ULONG_MIN" | "ULONG_MAX" => IntKind::ULong, + "LLONG_MIN" | "LLONG_MAX" => IntKind::LongLong, + "ULLONG_MIN" | "ULLONG_MAX" => IntKind::ULongLong, + _ => return None, + }) +} + fn default_macro_constant_type(ctx: &BindgenContext, value: i64) -> IntKind { if value < 0 || ctx.options().default_macro_constant_type == @@ -258,12 +307,71 @@ impl ClangSubItemParser for Var { let kind = ctx .parse_callbacks() .and_then(|c| c.int_macro(&name, value)) + .or_else(|| { + default_limit_constant_type(&name, value) + }) .unwrap_or_else(|| { default_macro_constant_type(ctx, value) }); (TypeKind::Int(kind), VarType::Int(value)) } + EvalResult::Cast(c, v) => { + let ty = c + .iter() + .map(|v| std::str::from_utf8(v).unwrap()) + .collect::>(); + + if let EvalResult::Int(Wrapping(value)) = *v { + let val = VarType::Int(value); + + let kind = match &ty[..] { + ["bool"] => IntKind::Bool, + ["char"] => IntKind::Char { + is_signed: value < 0, + }, + ["signed", "char"] => IntKind::SChar, + ["unsigned", "char"] => IntKind::UChar, + ["short"] => IntKind::Short, + ["unsigned", "short"] => IntKind::UShort, + ["int"] => IntKind::Int, + ["unsigned", "int"] => IntKind::UInt, + ["long"] => IntKind::Long, + ["unsigned", "long"] => IntKind::ULong, + ["long", "long"] => IntKind::LongLong, + ["unsigned", "long", "long"] => { + IntKind::ULongLong + } + ["int8_t"] => IntKind::I8, + ["uint8_t"] => IntKind::U8, + ["int16_t"] => IntKind::I16, + ["uint16_t"] => IntKind::U16, + ["int32_t"] => IntKind::I32, + ["uint32_t"] => IntKind::U32, + ["int64_t"] => IntKind::I64, + ["uint64_t"] => IntKind::U64, + [custom_type] => { + return Ok(ParseResult::New( + Var::new( + name, + None, + VarTypeId::Lazy( + custom_type.to_string(), + ), + Some(val), + true, + ), + Some(cursor), + )); + } + _ => return Err(ParseError::Continue), + }; + + (TypeKind::Int(kind), val) + } else { + return Err(ParseError::Continue); + } + } }; let ty = Item::builtin_type(type_kind, true, ctx);