Analyze mode view elements

This commit is contained in:
Lukas Scheller 2025-03-16 14:16:45 +01:00
parent 4f9caed19a
commit 5ce6365c85
2 changed files with 82 additions and 0 deletions

View file

@ -675,6 +675,7 @@ impl<'a> AnalyzeContext<'a, '_> {
name.decl.set_unique_reference(&record_element);
unassociated.remove(&record_element);
}
self.analyze_mode_view_element(&mut element.mode, scope, diagnostics)?;
}
if !unassociated.is_empty() {
diagnostics.add(
@ -686,6 +687,34 @@ impl<'a> AnalyzeContext<'a, '_> {
Ok(self.define(&mut view.ident, parent, AnyEntKind::View(typ), src_span))
}
fn analyze_mode_view_element(
&self,
mode: &mut ElementMode,
scope: &Scope<'a>,
diagnostics: &mut dyn DiagnosticHandler,
) -> EvalResult {
match mode {
ElementMode::Simple(_) => {}
ElementMode::Record(name) | ElementMode::Array(name) => {
let Some(resolved_name) =
as_fatal(self.name_resolve(scope, name.span, &mut name.item, diagnostics))?
else {
return Ok(());
};
match resolved_name {
ResolvedName::Final(ent) if matches!(ent.kind(), AnyEntKind::View(_)) => {}
_ => {
diagnostics.push(Diagnostic::mismatched_kinds(
name.span.pos(self.ctx),
"Expected view",
));
}
}
}
}
Ok(())
}
fn find_deferred_constant_declaration(
&self,
scope: &Scope<'a>,

View file

@ -617,3 +617,56 @@ end entity;
)],
)
}
#[test]
fn undefined_name_for_nested_view() {
let mut builder = LibraryBuilder::with_standard(VHDL2019);
let code = builder.code(
"libname",
"\
package test is
type my_rec_t is record
a : bit;
end record;
view invalid_view of my_rec_t is
a : view undefined_view;
end view;
end package;
",
);
check_diagnostics(
builder.analyze(),
vec![Diagnostic::new(
code.s1("undefined_view"),
"No declaration of 'undefined_view'",
ErrorCode::Unresolved,
)],
)
}
#[test]
fn view_that_is_not_a_view() {
let mut builder = LibraryBuilder::with_standard(VHDL2019);
let code = builder.code(
"libname",
"\
package test is
constant some_constant : bit := '1';
type my_rec_t is record
a : bit;
end record;
view invalid_view of my_rec_t is
a : view some_constant;
end view;
end package;
",
);
check_diagnostics(
builder.analyze(),
vec![Diagnostic::new(
code.s1("a : view some_constant;").s1("some_constant"),
"Expected view",
ErrorCode::MismatchedKinds,
)],
)
}