From 11477927cda4b66ca22e25f78b4dc485b8ad4f68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Cr=C3=AAte?= Date: Wed, 13 Dec 2023 17:55:09 -0500 Subject: [PATCH] record: Differentiate disguised vs pointer types Disguised types are not pointers, they're just typedefs to a private struct, while pointer types are typedef to a pointer to a private struct. Generate the right code for each. --- src/analysis/types.rs | 2 +- src/codegen/sys/lib_.rs | 8 ++++++-- src/library.rs | 5 ++++- src/library_postprocessing.rs | 2 +- src/parser.rs | 2 ++ 5 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/analysis/types.rs b/src/analysis/types.rs index e58b60221..d04fe5759 100644 --- a/src/analysis/types.rs +++ b/src/analysis/types.rs @@ -108,7 +108,7 @@ impl IsIncomplete for Class { impl IsIncomplete for Record { fn is_incomplete(&self, lib: &Library) -> bool { - if self.c_type == "GHookList" || self.disguised { + if self.c_type == "GHookList" || self.disguised || self.pointer { // Search for GHookList in sys codegen for rationale. false } else { diff --git a/src/codegen/sys/lib_.rs b/src/codegen/sys/lib_.rs index 11223d633..1ee73dbf0 100644 --- a/src/codegen/sys/lib_.rs +++ b/src/codegen/sys/lib_.rs @@ -452,7 +452,7 @@ fn generate_records(w: &mut dyn Write, env: &Env, records: &[&Record]) -> Result // 5. Thus, we use custom generated GHookList. // Hopefully someone will profit from all this. generate_ghooklist(w)?; - } else if record.disguised { + } else if record.disguised || record.pointer { generate_disguised(w, env, record)?; } else { let align = config.and_then(|c| c.align); @@ -499,7 +499,11 @@ fn generate_disguised(w: &mut dyn Write, env: &Env, record: &Record) -> Result<( cfg_condition(w, cfg_condition_, false, 0)?; generate_opaque_type(w, &format!("_{}", record.c_type))?; cfg_condition(w, cfg_condition_, false, 0)?; - writeln!(w, "pub type {name} = *mut _{name};", name = record.c_type)?; + if record.pointer { + writeln!(w, "pub type {name} = *mut _{name};", name = record.c_type)?; + } else { + writeln!(w, "pub type {name} = _{name};", name = record.c_type)?; + } writeln!(w) } diff --git a/src/library.rs b/src/library.rs index 7d417c839..5cdbd2a0f 100644 --- a/src/library.rs +++ b/src/library.rs @@ -427,8 +427,11 @@ pub struct Record { pub deprecated_version: Option, pub doc: Option, pub doc_deprecated: Option, - /// A 'disguised' record is one where the c:type is a typedef that + /// A 'pointer' record is one where the c:type is a typedef that /// doesn't look like a pointer, but is internally: typedef struct _X *X; + pub pointer: bool, + /// A 'disguised' record is one where the c:type is a typedef to + /// a struct whose content and size are unknown, it is :typedef struct _X X; pub disguised: bool, } diff --git a/src/library_postprocessing.rs b/src/library_postprocessing.rs index 68661d726..11747c6f5 100644 --- a/src/library_postprocessing.rs +++ b/src/library_postprocessing.rs @@ -460,7 +460,7 @@ impl Library { self.find_type(ns_id as u16, klass.type_struct.as_ref().unwrap()) { if let Type::Record(record) = self.type_(class_record_tid) { - !record.disguised + !record.disguised && !record.pointer } else { unreachable!("Type {} with non-record class", full_name); } diff --git a/src/parser.rs b/src/parser.rs index a754fbc13..cdbcb66f6 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -305,6 +305,7 @@ impl Library { let gtype_struct_for = elem.attr("is-gtype-struct-for"); let version = self.read_version(parser, ns_id, elem)?; let deprecated_version = self.read_deprecated_version(parser, ns_id, elem)?; + let pointer = elem.attr_bool("pointer", false); let disguised = elem.attr_bool("disguised", false); let mut fields = Vec::new(); @@ -406,6 +407,7 @@ impl Library { doc, doc_deprecated, disguised, + pointer, symbol_prefix, });