From 887077dc20d45b899dc37fd78be76869c130aa61 Mon Sep 17 00:00:00 2001 From: Alex Zepeda Date: Mon, 5 Jan 2026 17:08:29 -0800 Subject: [PATCH 1/3] Permit duplicate "reserved" fields. Renesas uses multiple fields named `Reserved` within the same register in a few different places in e.g. the RA4M1 SVD. This would preserve the existing behavior of forbidding duplicate field names except where it appears to be deliberate. Alternatively should duplicate field names be allowed and then deduplicated in the sanitize transform? --- src/svd2ir.rs | 14 +++++++++++++- src/transform/sanitize.rs | 20 +++++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/svd2ir.rs b/src/svd2ir.rs index 8d65855..246de9b 100644 --- a/src/svd2ir.rs +++ b/src/svd2ir.rs @@ -50,6 +50,7 @@ pub fn convert_peripheral(ir: &mut IR, p: &svd::Peripheral) -> anyhow::Result<() if let Some(fields) = &r.fields { let mut fieldset_name = block.name.clone(); + let mut field_name_counts: BTreeMap = BTreeMap::new(); fieldset_name.push(util::replace_suffix(&r.name, "")); fieldsets.push(ProtoFieldset { name: fieldset_name.clone(), @@ -67,7 +68,18 @@ pub fn convert_peripheral(ir: &mut IR, p: &svd::Peripheral) -> anyhow::Result<() let mut enum_write = None; let mut enum_readwrite = None; - let field_name = util::replace_suffix(&f.name, ""); + let mut field_name = util::replace_suffix(&f.name, ""); + + let field_name_count = + field_name_counts.entry(field_name.clone()).or_insert(0); + *field_name_count += 1; + if *field_name_count > 1 { + if field_name.contains("eserved") { + field_name = format!("{}{}", field_name, field_name_count); + } else { + error!("Duplicate Field: {}::{}", r.name, field_name); + } + } for e in &f.enumerated_values { let e = if let Some(derived_from) = &e.derived_from { diff --git a/src/transform/sanitize.rs b/src/transform/sanitize.rs index c1d4524..1d323e9 100644 --- a/src/transform/sanitize.rs +++ b/src/transform/sanitize.rs @@ -28,6 +28,10 @@ impl Sanitize { rename_duplicate_variants(enumm); } + for (_, fieldset) in ir.fieldsets.iter_mut() { + rename_duplicate_fields(fieldset); + } + Ok(()) } } @@ -87,8 +91,22 @@ fn rename_duplicate_variants(enumm: &mut crate::ir::Enum) { for v in &mut enumm.variants { if name_counts.get(&v.name).is_some_and(|&c| c > 1) { v.name = format!("{}_{:x}", v.name, v.value); - // increment new name to catch cascading name collisons + // increment new name to catch cascading name collisions *name_counts.entry(v.name.clone()).or_insert(0) += 1; } } } + +fn rename_duplicate_fields(fieldset: &mut crate::ir::FieldSet) { + use std::collections::BTreeMap; + + let mut name_counts: BTreeMap = BTreeMap::new(); + + for f in fieldset.fields.iter_mut() { + let count = name_counts.entry(f.name.clone()).or_insert(0); + *count += 1; + if *count > 1 { + f.name = format!("{}_{count:x}", f.name); + } + } +} From ee142caa2601166eca2525ea125dc96ebb93c0e3 Mon Sep 17 00:00:00 2001 From: Alex Zepeda Date: Sat, 11 Apr 2026 22:52:01 -0700 Subject: [PATCH 2/3] Fix up merge --- src/transform/sanitize.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/transform/sanitize.rs b/src/transform/sanitize.rs index 0485a58..f3ac83a 100644 --- a/src/transform/sanitize.rs +++ b/src/transform/sanitize.rs @@ -158,6 +158,20 @@ pub(crate) fn rename_duplicate_variants(enumm: &mut crate::ir::Enum) { } } +fn rename_duplicate_fields(fieldset: &mut crate::ir::FieldSet) { + use std::collections::BTreeMap; + + let mut name_counts: BTreeMap = BTreeMap::new(); + + for f in fieldset.fields.iter_mut() { + let count = name_counts.entry(f.name.clone()).or_insert(0); + *count += 1; + if *count > 1 { + f.name = format!("{}_{count:x}", f.name); + } + } +} + /// List of chars that some vendors use in their peripheral/field names but /// that are not valid in Rust ident const INVALID_CHARS: &[char] = &['(', ')', '[', ']', '/', ' ', '-']; From e1624ccce2a1c88e2a61ae6dd2327845a1ae6a25 Mon Sep 17 00:00:00 2001 From: Alex Zepeda Date: Sat, 11 Apr 2026 22:59:54 -0700 Subject: [PATCH 3/3] Update dedup logic. - Remove deduplication logic from sanitize - Allow duplicate names for any value, not just 'reserved' --- src/svd2ir.rs | 6 +----- src/transform/sanitize.rs | 18 ------------------ 2 files changed, 1 insertion(+), 23 deletions(-) diff --git a/src/svd2ir.rs b/src/svd2ir.rs index c699a31..a23b175 100644 --- a/src/svd2ir.rs +++ b/src/svd2ir.rs @@ -81,11 +81,7 @@ pub fn convert_peripheral(ir: &mut IR, p: &svd::Peripheral) -> anyhow::Result<() field_name_counts.entry(field_name.clone()).or_insert(0); *field_name_count += 1; if *field_name_count > 1 { - if field_name.contains("eserved") { - field_name = format!("{}{}", field_name, field_name_count); - } else { - error!("Duplicate Field: {}::{}", r.name, field_name); - } + field_name = format!("{}{}", field_name, field_name_count); } for e in &f.enumerated_values { diff --git a/src/transform/sanitize.rs b/src/transform/sanitize.rs index f3ac83a..afcf80e 100644 --- a/src/transform/sanitize.rs +++ b/src/transform/sanitize.rs @@ -101,10 +101,6 @@ impl Sanitize { rename_duplicate_variants(enumm); } - for (_, fieldset) in ir.fieldsets.iter_mut() { - rename_duplicate_fields(fieldset); - } - Ok(()) } } @@ -158,20 +154,6 @@ pub(crate) fn rename_duplicate_variants(enumm: &mut crate::ir::Enum) { } } -fn rename_duplicate_fields(fieldset: &mut crate::ir::FieldSet) { - use std::collections::BTreeMap; - - let mut name_counts: BTreeMap = BTreeMap::new(); - - for f in fieldset.fields.iter_mut() { - let count = name_counts.entry(f.name.clone()).or_insert(0); - *count += 1; - if *count > 1 { - f.name = format!("{}_{count:x}", f.name); - } - } -} - /// List of chars that some vendors use in their peripheral/field names but /// that are not valid in Rust ident const INVALID_CHARS: &[char] = &['(', ')', '[', ']', '/', ' ', '-'];