summaryrefslogtreecommitdiff
path: root/src/codegen/impl_debug.rs
diff options
context:
space:
mode:
authorChristian Poveda <christian.poveda@ferrous-systems.com>2022-09-23 21:36:14 -0500
committerChristian Poveda <christian.poveda@ferrous-systems.com>2022-10-04 20:47:17 -0500
commit0296f9e86c7756e718b6b82836ce1e09b5f8d08a (patch)
treeb5954c6680b243c0b1671a80ea973ef90877e462 /src/codegen/impl_debug.rs
parenta900f8f863d1313ad76603234aaeea22bb9ba7b3 (diff)
split the repo into a workspace
remove `clap` dependency :tada: update the book installation instructions
Diffstat (limited to 'src/codegen/impl_debug.rs')
-rw-r--r--src/codegen/impl_debug.rs245
1 files changed, 0 insertions, 245 deletions
diff --git a/src/codegen/impl_debug.rs b/src/codegen/impl_debug.rs
deleted file mode 100644
index 0e2cd33a..00000000
--- a/src/codegen/impl_debug.rs
+++ /dev/null
@@ -1,245 +0,0 @@
-use crate::ir::comp::{BitfieldUnit, CompKind, Field, FieldData, FieldMethods};
-use crate::ir::context::BindgenContext;
-use crate::ir::item::{HasTypeParamInArray, IsOpaque, Item, ItemCanonicalName};
-use crate::ir::ty::{TypeKind, RUST_DERIVE_IN_ARRAY_LIMIT};
-
-pub fn gen_debug_impl(
- ctx: &BindgenContext,
- fields: &[Field],
- item: &Item,
- kind: CompKind,
-) -> proc_macro2::TokenStream {
- let struct_name = item.canonical_name(ctx);
- let mut format_string = format!("{} {{{{ ", struct_name);
- let mut tokens = vec![];
-
- if item.is_opaque(ctx, &()) {
- format_string.push_str("opaque");
- } else {
- match kind {
- CompKind::Union => {
- format_string.push_str("union");
- }
- CompKind::Struct => {
- let processed_fields = fields.iter().filter_map(|f| match f {
- Field::DataMember(ref fd) => fd.impl_debug(ctx, ()),
- Field::Bitfields(ref bu) => bu.impl_debug(ctx, ()),
- });
-
- for (i, (fstring, toks)) in processed_fields.enumerate() {
- if i > 0 {
- format_string.push_str(", ");
- }
- tokens.extend(toks);
- format_string.push_str(&fstring);
- }
- }
- }
- }
-
- format_string.push_str(" }}");
- tokens.insert(0, quote! { #format_string });
-
- let prefix = ctx.trait_prefix();
-
- quote! {
- fn fmt(&self, f: &mut ::#prefix::fmt::Formatter<'_>) -> ::#prefix ::fmt::Result {
- write!(f, #( #tokens ),*)
- }
- }
-}
-
-/// A trait for the things which we can codegen tokens that contribute towards a
-/// generated `impl Debug`.
-pub trait ImplDebug<'a> {
- /// Any extra parameter required by this a particular `ImplDebug` implementation.
- type Extra;
-
- /// Generate a format string snippet to be included in the larger `impl Debug`
- /// format string, and the code to get the format string's interpolation values.
- fn impl_debug(
- &self,
- ctx: &BindgenContext,
- extra: Self::Extra,
- ) -> Option<(String, Vec<proc_macro2::TokenStream>)>;
-}
-
-impl<'a> ImplDebug<'a> for FieldData {
- type Extra = ();
-
- fn impl_debug(
- &self,
- ctx: &BindgenContext,
- _: Self::Extra,
- ) -> Option<(String, Vec<proc_macro2::TokenStream>)> {
- if let Some(name) = self.name() {
- ctx.resolve_item(self.ty()).impl_debug(ctx, name)
- } else {
- None
- }
- }
-}
-
-impl<'a> ImplDebug<'a> for BitfieldUnit {
- type Extra = ();
-
- fn impl_debug(
- &self,
- ctx: &BindgenContext,
- _: Self::Extra,
- ) -> Option<(String, Vec<proc_macro2::TokenStream>)> {
- let mut format_string = String::new();
- let mut tokens = vec![];
- for (i, bitfield) in self.bitfields().iter().enumerate() {
- if i > 0 {
- format_string.push_str(", ");
- }
-
- if let Some(bitfield_name) = bitfield.name() {
- format_string.push_str(&format!("{} : {{:?}}", bitfield_name));
- let getter_name = bitfield.getter_name();
- let name_ident = ctx.rust_ident_raw(getter_name);
- tokens.push(quote! {
- self.#name_ident ()
- });
- }
- }
-
- Some((format_string, tokens))
- }
-}
-
-impl<'a> ImplDebug<'a> for Item {
- type Extra = &'a str;
-
- fn impl_debug(
- &self,
- ctx: &BindgenContext,
- name: &str,
- ) -> Option<(String, Vec<proc_macro2::TokenStream>)> {
- let name_ident = ctx.rust_ident(name);
-
- // We don't know if blocklisted items `impl Debug` or not, so we can't
- // add them to the format string we're building up.
- if !ctx.allowlisted_items().contains(&self.id()) {
- return None;
- }
-
- let ty = match self.as_type() {
- Some(ty) => ty,
- None => {
- return None;
- }
- };
-
- fn debug_print(
- name: &str,
- name_ident: proc_macro2::TokenStream,
- ) -> Option<(String, Vec<proc_macro2::TokenStream>)> {
- Some((
- format!("{}: {{:?}}", name),
- vec![quote! {
- self.#name_ident
- }],
- ))
- }
-
- match *ty.kind() {
- // Handle the simple cases.
- TypeKind::Void |
- TypeKind::NullPtr |
- TypeKind::Int(..) |
- TypeKind::Float(..) |
- TypeKind::Complex(..) |
- TypeKind::Function(..) |
- TypeKind::Enum(..) |
- TypeKind::Reference(..) |
- TypeKind::UnresolvedTypeRef(..) |
- TypeKind::ObjCInterface(..) |
- TypeKind::ObjCId |
- TypeKind::Comp(..) |
- TypeKind::ObjCSel => debug_print(name, quote! { #name_ident }),
-
- TypeKind::TemplateInstantiation(ref inst) => {
- if inst.is_opaque(ctx, self) {
- Some((format!("{}: opaque", name), vec![]))
- } else {
- debug_print(name, quote! { #name_ident })
- }
- }
-
- // The generic is not required to implement Debug, so we can not debug print that type
- TypeKind::TypeParam => {
- Some((format!("{}: Non-debuggable generic", name), vec![]))
- }
-
- TypeKind::Array(_, len) => {
- // Generics are not required to implement Debug
- if self.has_type_param_in_array(ctx) {
- Some((
- format!("{}: Array with length {}", name, len),
- vec![],
- ))
- } else if len < RUST_DERIVE_IN_ARRAY_LIMIT ||
- ctx.options().rust_features().larger_arrays
- {
- // The simple case
- debug_print(name, quote! { #name_ident })
- } else if ctx.options().use_core {
- // There is no String in core; reducing field visibility to avoid breaking
- // no_std setups.
- Some((format!("{}: [...]", name), vec![]))
- } else {
- // Let's implement our own print function
- Some((
- format!("{}: [{{}}]", name),
- vec![quote! {
- self.#name_ident
- .iter()
- .enumerate()
- .map(|(i, v)| format!("{}{:?}", if i > 0 { ", " } else { "" }, v))
- .collect::<String>()
- }],
- ))
- }
- }
- TypeKind::Vector(_, len) => {
- if ctx.options().use_core {
- // There is no format! in core; reducing field visibility to avoid breaking
- // no_std setups.
- Some((format!("{}(...)", name), vec![]))
- } else {
- let self_ids = 0..len;
- Some((
- format!("{}({{}})", name),
- vec![quote! {
- #(format!("{:?}", self.#self_ids)),*
- }],
- ))
- }
- }
-
- TypeKind::ResolvedTypeRef(t) |
- TypeKind::TemplateAlias(t, _) |
- TypeKind::Alias(t) |
- TypeKind::BlockPointer(t) => {
- // We follow the aliases
- ctx.resolve_item(t).impl_debug(ctx, name)
- }
-
- TypeKind::Pointer(inner) => {
- let inner_type = ctx.resolve_type(inner).canonical_type(ctx);
- match *inner_type.kind() {
- TypeKind::Function(ref sig)
- if !sig.function_pointers_can_derive() =>
- {
- Some((format!("{}: FunctionPointer", name), vec![]))
- }
- _ => debug_print(name, quote! { #name_ident }),
- }
- }
-
- TypeKind::Opaque => None,
- }
- }
-}