From d1a0892a2cce98edee549bc3a490998c00da453d Mon Sep 17 00:00:00 2001 From: Jonatan Waern Date: Wed, 20 Aug 2025 15:19:30 +0200 Subject: [PATCH 1/8] Fix debug print of rows and columns --- src/span/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/span/mod.rs b/src/span/mod.rs index 7583114..18a979f 100644 --- a/src/span/mod.rs +++ b/src/span/mod.rs @@ -18,7 +18,7 @@ pub struct Column(pub u32, PhantomData); impl Debug for Column { fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> { - write!(f, "Col<{}I>({}))", + write!(f, "Col<{}I>({})", I::MINIMUM_VALUE, &self.0) } @@ -93,7 +93,7 @@ pub struct Row(pub u32, PhantomData); impl Debug for Row { fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> { - write!(f, "Row<{}I>({}))", + write!(f, "Row<{}I>({})", I::MINIMUM_VALUE, &self.0) } From cdec84b4befcdcc4e8fd45dc9aab26badeef5441 Mon Sep 17 00:00:00 2001 From: Jonatan Waern Date: Fri, 22 Aug 2025 15:21:21 +0200 Subject: [PATCH 2/8] Correct location used for parameter symbols Signed-off-by: Jonatan Waern --- src/analysis/templating/objects.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/analysis/templating/objects.rs b/src/analysis/templating/objects.rs index 89c4fe8..37f21e6 100644 --- a/src/analysis/templating/objects.rs +++ b/src/analysis/templating/objects.rs @@ -656,7 +656,7 @@ impl DMLNamedMember for DMLShallowObjectVariant { DMLShallowObjectVariant::Session(d) | DMLShallowObjectVariant::Saved(d) => &d.declaration.name.span, DMLShallowObjectVariant::Parameter(p) => - p.get_likely_definition().span(), + p.get_likely_definition().loc_span(), DMLShallowObjectVariant::Constant(c) => c.loc_span(), DMLShallowObjectVariant::Hook(h) => From c5c588f880cc599cdd1d9c716d4d9557a69ef348 Mon Sep 17 00:00:00 2001 From: Jonatan Waern Date: Thu, 21 Aug 2025 14:43:55 +0200 Subject: [PATCH 3/8] Correct timing and strategy of object param invariant check Signed-off-by: Jonatan Waern --- src/analysis/mod.rs | 33 ++++++++++++++++++++++++++++++ src/analysis/templating/objects.rs | 26 ----------------------- 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/src/analysis/mod.rs b/src/analysis/mod.rs index 75caca0..eb76f06 100644 --- a/src/analysis/mod.rs +++ b/src/analysis/mod.rs @@ -2028,6 +2028,7 @@ fn add_new_method_scope_symbols(method: &Arc, } } + impl DeviceAnalysis { pub fn new(root: IsolatedAnalysis, timed_bases: Vec>, @@ -2212,6 +2213,10 @@ impl DeviceAnalysis { |spec|*spec.loc_span()))); } } + info!("Invariant check"); + for obj in device.objects.values() { + device.param_invariants(obj, &mut errors); + } for error in errors { device.errors.entry(error.span.path()) @@ -2223,6 +2228,34 @@ impl DeviceAnalysis { info!("Done with device"); Ok(device) } + + fn param_invariants(&self, + obj: &DMLCompositeObject, + report: &mut Vec) { + match &obj.kind { + // TODO: Check 'name' parameter towards 'ident' parameter + CompObjectKind::Register => { + // NOTE: 'offset' is checked by the requirement of + // the register template. Might be better to give + // a nicer error here + match self.lookup_def_in_comp_object( + obj, "size", None) { + // TODO: verify size is an integer + ReferenceMatch::Found(_) => (), + _ => { + report.push(DMLError { + span: obj.declloc, + description: "No assignmenton to 'size' parameter \ + in register".to_string(), + related: vec![], + severity: Some(DiagnosticSeverity::ERROR), + }); + }, + } + }, + _ => (), + } + } } pub fn from_device_and_bases<'a>(_device: &'a IsolatedAnalysis, diff --git a/src/analysis/templating/objects.rs b/src/analysis/templating/objects.rs index 37f21e6..efb6d47 100644 --- a/src/analysis/templating/objects.rs +++ b/src/analysis/templating/objects.rs @@ -1313,31 +1313,6 @@ fn resolve_parameter(obj_loc: &ZeroSpan, ) } -#[allow(clippy::single_match)] -fn param_invariants(object:&mut DMLCompositeObject, - report: &mut Vec) { - // TODO: Check 'name' parameter towards 'ident' parameter - match &object.kind { - CompObjectKind::Register => { - // NOTE: 'offset' is checked by the requirement of - // the register template. Might be better to give - // a nicer error here - if let Some(_size) = object.get_param("size") { - // TODO: verify size is an integer - } else { - report.push(DMLError { - span: object.declloc, - description: "Missing declaration for 'size' parameter \ - in register".to_string(), - related: vec![], - severity: Some(DiagnosticSeverity::ERROR), - }); - } - }, - _ => (), - } -} - fn create_object_instance(loc: Option, all_decls: Vec>, identity: &DMLString, @@ -2255,7 +2230,6 @@ pub fn make_object(loc: ZeroSpan, add_subobjs(new_obj_key, subobj_keys, container); { let new_obj = container.get_mut(new_obj_key).unwrap(); - param_invariants(new_obj, report); let trait_method_map = merge_impl_maps(&identity.val, &loc, new_obj.templates.values().map( |t|&t.traitspec), From 9a0f89b97d5d21b6b574789b98e67f99ba2e5997 Mon Sep 17 00:00:00 2001 From: Jonatan Waern Date: Fri, 22 Aug 2025 15:47:34 +0200 Subject: [PATCH 4/8] Disable check for 'size' in register This will rely on future constant-folding, in order to ascertain that an actual value is found. Signed-off-by: Jonatan Waern --- CHANGELOG.md | 2 ++ src/analysis/mod.rs | 34 +++++++++++++++++++--------------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d92fdf8..84bbea5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ correctly parsed. - You can now annotate dml source to disable reporting of specific lints for specific files or lines, see [USAGE.md](USAGE.md) for instructions on how to use it +- Disabled the invariant check for the parameter 'size' to be set on register + objects. Will be re-enabled when constant-folding is added to the DLS. ## 0.9.12 - Added 'simics\_util\_vect' as a known provisional (with no DLS semantics) diff --git a/src/analysis/mod.rs b/src/analysis/mod.rs index eb76f06..d0b45a4 100644 --- a/src/analysis/mod.rs +++ b/src/analysis/mod.rs @@ -2229,29 +2229,33 @@ impl DeviceAnalysis { Ok(device) } + #[allow(clippy::ptr_arg)] fn param_invariants(&self, obj: &DMLCompositeObject, - report: &mut Vec) { + _report: &mut Vec) { + #[allow(clippy::single_match)] match &obj.kind { // TODO: Check 'name' parameter towards 'ident' parameter CompObjectKind::Register => { + // TODO: Cannot be sufficiently checked until + // constant-folding is in // NOTE: 'offset' is checked by the requirement of // the register template. Might be better to give // a nicer error here - match self.lookup_def_in_comp_object( - obj, "size", None) { - // TODO: verify size is an integer - ReferenceMatch::Found(_) => (), - _ => { - report.push(DMLError { - span: obj.declloc, - description: "No assignmenton to 'size' parameter \ - in register".to_string(), - related: vec![], - severity: Some(DiagnosticSeverity::ERROR), - }); - }, - } + // match self.lookup_def_in_comp_object( + // obj, "size", None) { + // // TODO: verify size is an integer + // ReferenceMatch::Found(_) => (), + // _ => { + // report.push(DMLError { + // span: obj.declloc, + // description: "No assignment to 'size' parameter \ + // in register".to_string(), + // related: vec![], + // severity: Some(DiagnosticSeverity::ERROR), + // }); + // }, + // } }, _ => (), } From 2674f0826fcd2534c4e5aadb8abfd20b89ca143f Mon Sep 17 00:00:00 2001 From: Jonatan Waern Date: Wed, 27 Aug 2025 11:46:04 +0200 Subject: [PATCH 5/8] Fix conditions to add a in-each spec to an object Signed-off-by: Jonatan Waern --- src/analysis/templating/objects.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/analysis/templating/objects.rs b/src/analysis/templating/objects.rs index efb6d47..f8a516e 100644 --- a/src/analysis/templating/objects.rs +++ b/src/analysis/templating/objects.rs @@ -951,7 +951,6 @@ fn add_template_specs(obj_specs: &mut Vec>, while let Some((_, tpl)) = queue.pop() { // TODO: here we would have to consider cond when conditional // is/imports exist - if used_templates.contains(&tpl.name) { continue; } @@ -961,6 +960,7 @@ fn add_template_specs(obj_specs: &mut Vec>, let mut modifications = vec![]; if let Some(templ_specs) = each_stmts.get(&tpl.name) { for (needed_templates, spec) in templ_specs { + let mut can_add = true; for templ in needed_templates { if !used_templates.contains(templ.as_str()) { // We will need to re-add a check for this template, @@ -968,15 +968,17 @@ fn add_template_specs(obj_specs: &mut Vec>, modifications.push((templ.clone(), needed_templates.clone(), Arc::clone(spec))); + can_add = false; break; - } else { - queue.extend(spec.instantiations.values() - .flat_map(|v|v.iter()) - .map(|t|(spec.condition.clone(), - Arc::clone(t)))); - obj_specs.push(Arc::clone(spec)); } } + if can_add { + queue.extend(spec.instantiations.values() + .flat_map(|v|v.iter()) + .map(|t|(spec.condition.clone(), + Arc::clone(t)))); + obj_specs.push(Arc::clone(spec)); + } } } for (name, templs, spec) in modifications { From 53644c8f9e111ad83faca5a7accb8c7fe1defac8 Mon Sep 17 00:00:00 2001 From: Jonatan Waern Date: Wed, 27 Aug 2025 16:13:41 +0200 Subject: [PATCH 6/8] Fix error of untracked in-eachs at top-level Signed-off-by: Jonatan Waern --- CHANGELOG.md | 1 + src/analysis/structure/toplevel.rs | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 84bbea5..1a30fc8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ see [USAGE.md](USAGE.md) for instructions on how to use it - Disabled the invariant check for the parameter 'size' to be set on register objects. Will be re-enabled when constant-folding is added to the DLS. +- Fixed issue where statements under top-level in-eachs were not correctly tracked. ## 0.9.12 - Added 'simics\_util\_vect' as a known provisional (with no DLS semantics) diff --git a/src/analysis/structure/toplevel.rs b/src/analysis/structure/toplevel.rs index 6f25ff8..c4016b4 100644 --- a/src/analysis/structure/toplevel.rs +++ b/src/analysis/structure/toplevel.rs @@ -659,8 +659,20 @@ impl TopLevel { |stmnt|ObjectDecl::always(stmnt)).collect(); let mut errors = statements.errors.iter().map( |stmnt|ObjectDecl::always(stmnt)).collect(); - let mut ineachs = statements.ineachs.iter().map( - |stmnt|ObjectDecl::always(stmnt)).collect(); + let mut ineachs = vec![]; + + for ineach in &statements.ineachs { + let spec = flatten_hashif_branch(StatementContext::Object, + &ineach.statements, + vec![], report); + ineachs.push( + ObjectDecl { + cond: ExistCondition::Always, + obj: ineach.clone(), + spec, + }); + } + let mut templates = vec![]; let mut loggroups = vec![]; let mut constants = vec![]; From 1ba62e85938e8eddc71b6e18e6fd266ce9b4beb4 Mon Sep 17 00:00:00 2001 From: Jonatan Waern Date: Mon, 1 Sep 2025 13:00:32 +0200 Subject: [PATCH 7/8] Refactor new-device-analysis method It was getting to an unwieldy length, assists with method-level profiling Signed-off-by: Jonatan Waern , } +impl SymbolStorage { + pub fn all_symbols<'a>(&'a self) -> impl Iterator { + self.template_symbols.values() + .chain(self.param_symbols.values().flat_map(|h|h.values())) + .chain(self.object_symbols.values()) + .chain(self.method_symbols.values()) + .chain(self.variable_symbols.values()) + } +} + // This maps non-auth symbol decls to auth decl // and references to the symbol decl they ref type ReferenceStorage = HashMap>; @@ -2030,6 +2040,78 @@ fn add_new_method_scope_symbols(method: &Arc, impl DeviceAnalysis { + fn make_templates_traits(start_of_file: &ZeroSpan, + rank_maker: &mut RankMaker, + unique_templates: &HashMap< + &str, &ObjectDecl