Skip to content

Commit 4570859

Browse files
committed
Use FormalRegion
1 parent 2790efe commit 4570859

File tree

3 files changed

+54
-48
lines changed

3 files changed

+54
-48
lines changed

vhdl_lang/src/analysis/concurrent.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -199,14 +199,16 @@ impl<'a> AnalyzeContext<'a> {
199199
)?;
200200

201201
if let NamedEntityKind::Entity(ent_region) = ent.kind() {
202+
let formal_region = ent_region.to_entity_formal();
203+
202204
self.analyze_assoc_elems_with_formal_region(
203-
ent_region,
205+
&formal_region,
204206
parent,
205207
&mut instance.generic_map,
206208
diagnostics,
207209
)?;
208210
self.analyze_assoc_elems_with_formal_region(
209-
ent_region,
211+
&formal_region,
210212
parent,
211213
&mut instance.port_map,
212214
diagnostics,
@@ -234,14 +236,15 @@ impl<'a> AnalyzeContext<'a> {
234236
)?;
235237

236238
if let NamedEntityKind::Component(ent_region) = ent.kind() {
239+
let formal_region = ent_region.to_entity_formal();
237240
self.analyze_assoc_elems_with_formal_region(
238-
ent_region,
241+
&formal_region,
239242
parent,
240243
&mut instance.generic_map,
241244
diagnostics,
242245
)?;
243246
self.analyze_assoc_elems_with_formal_region(
244-
ent_region,
247+
&formal_region,
245248
parent,
246249
&mut instance.port_map,
247250
diagnostics,

vhdl_lang/src/analysis/region.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use super::formal_region::FormalRegion;
2+
use super::formal_region::InterfaceEnt;
13
// This Source Code Form is subject to the terms of the Mozilla Public
24
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
35
// You can obtain one at http://mozilla.org/MPL/2.0/.
@@ -251,6 +253,21 @@ impl<'a> Region<'a> {
251253
self
252254
}
253255

256+
pub fn to_entity_formal(&self) -> FormalRegion {
257+
// @TODO separate generics and ports
258+
let mut entities = Vec::with_capacity(self.entities.len());
259+
for ent in self.entities.values() {
260+
if let NamedEntities::Single(ent) = ent {
261+
if let Some(ent) = InterfaceEnt::from_any(ent.clone()) {
262+
entities.push(ent);
263+
}
264+
}
265+
}
266+
// Sorting by source file position gives declaration order
267+
entities.sort_by_key(|ent| ent.decl_pos().map(|pos| pos.range().start));
268+
FormalRegion::new(entities)
269+
}
270+
254271
pub fn extend(region: &'a Region<'a>, parent: Option<&'a Region<'a>>) -> Region<'a> {
255272
let kind = match region.kind {
256273
RegionKind::PackageDeclaration => RegionKind::PackageBody,

vhdl_lang/src/analysis/semantic.rs

Lines changed: 30 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
//
66
// Copyright (c) 2018, Olof Kraigher olof.kraigher@gmail.com
77
use super::analyze::*;
8+
use super::formal_region::FormalRegion;
9+
use super::formal_region::InterfaceEnt;
810
use super::region::*;
911
use super::target::AssignmentType;
1012
use crate::ast::Range;
@@ -416,58 +418,45 @@ impl<'a> AnalyzeContext<'a> {
416418
Ok(())
417419
}
418420

421+
// Returns None when the formal name is itself selected
422+
// This mostly happens with records in ports
423+
// It could also could also happen in function calls in very rare cases
424+
// We ignore function calls for now
419425
pub fn resolve_formal_name(
420426
&self,
421-
formal_region: &Region<'_>,
427+
formal_region: &FormalRegion,
422428
region: &Region<'_>,
423429
name_pos: &SrcPos,
424430
name: &mut Name,
425431
diagnostics: &mut dyn DiagnosticHandler,
426-
) -> FatalResult<Option<NamedEntities>> {
432+
) -> AnalysisResult<Option<InterfaceEnt>> {
427433
match name {
428434
Name::Selected(prefix, suffix) => {
429435
suffix.clear_reference();
430436

431-
match self.resolve_formal_name(
437+
let prefix_ent = self.resolve_formal_name(
432438
formal_region,
433439
region,
434440
&prefix.pos,
435441
&mut prefix.item,
436442
diagnostics,
437-
)? {
438-
Some(NamedEntities::Single(ref named_entity)) => {
439-
match self.lookup_selected(&prefix.pos, named_entity, suffix) {
440-
Ok(visible) => {
441-
suffix.set_reference(&visible);
442-
Ok(Some(visible))
443-
}
444-
Err(err) => {
445-
err.add_to(diagnostics)?;
446-
Ok(None)
447-
}
448-
}
449-
}
450-
Some(NamedEntities::Overloaded(..)) => Ok(None),
451-
None => Ok(None),
443+
)?;
444+
445+
if let Some(prefix_ent) = prefix_ent {
446+
let visible = self.lookup_selected(&prefix.pos, &prefix_ent, suffix)?;
447+
suffix.set_reference(&visible);
448+
// @TODO this could be a field of a port that is a record, we ingore these for now
452449
}
453-
}
454450

455-
Name::SelectedAll(_) => {
456-
diagnostics.error(name_pos, "Invalid formal");
457451
Ok(None)
458452
}
453+
454+
Name::SelectedAll(_) => Err(Diagnostic::error(name_pos, "Invalid formal").into()),
459455
Name::Designator(designator) => {
460456
designator.clear_reference();
461-
match formal_region.lookup_within(name_pos, designator.designator()) {
462-
Ok(visible) => {
463-
designator.set_reference(&visible);
464-
Ok(Some(visible))
465-
}
466-
Err(diagnostic) => {
467-
diagnostics.push(diagnostic);
468-
Ok(None)
469-
}
470-
}
457+
let ent = formal_region.lookup(name_pos, designator.designator())?;
458+
designator.set_unique_reference(ent.inner());
459+
Ok(Some(ent))
471460
}
472461
Name::Indexed(ref mut prefix, ref mut exprs) => {
473462
self.resolve_formal_name(
@@ -506,10 +495,7 @@ impl<'a> AnalyzeContext<'a> {
506495
return Ok(None);
507496
};
508497

509-
if formal_region
510-
.lookup_within(name_pos, prefix.designator())
511-
.is_err()
512-
{
498+
if formal_region.lookup(name_pos, prefix.designator()).is_err() {
513499
// The prefix of the name was not found in the formal region
514500
// it must be a type conversion or a single parameter function call
515501
self.resolve_name(region, &fcall.name.pos, &mut fcall.name.item, diagnostics)?;
@@ -545,7 +531,7 @@ impl<'a> AnalyzeContext<'a> {
545531
&mut fcall.name.item,
546532
diagnostics,
547533
)? {
548-
Some(NamedEntities::Single(ent)) => {
534+
Some(ent) => {
549535
if ent.actual_kind().is_type() {
550536
// A type conversion
551537
// @TODO Ignore for now
@@ -558,7 +544,9 @@ impl<'a> AnalyzeContext<'a> {
558544
*name = indexed_name;
559545

560546
if let Name::Indexed(ref mut prefix, ref mut indexes) = name {
561-
if let Some(type_mark) = type_mark_of_sliced_or_indexed(&ent) {
547+
if let Some(type_mark) =
548+
type_mark_of_sliced_or_indexed(ent.inner())
549+
{
562550
if let Err(err) = self.analyze_indexed_name(
563551
region,
564552
name_pos,
@@ -592,10 +580,6 @@ impl<'a> AnalyzeContext<'a> {
592580
)?;
593581
}
594582
}
595-
Some(NamedEntities::Overloaded(..)) => {
596-
// @TODO check function arguments
597-
self.analyze_assoc_elems(region, &mut fcall.parameters, diagnostics)?;
598-
}
599583
None => {
600584
self.analyze_assoc_elems(region, &mut fcall.parameters, diagnostics)?;
601585
}
@@ -613,20 +597,22 @@ impl<'a> AnalyzeContext<'a> {
613597

614598
pub fn analyze_assoc_elems_with_formal_region(
615599
&self,
616-
formal_region: &Region<'_>,
600+
formal_region: &FormalRegion,
617601
region: &Region<'_>,
618602
elems: &mut [AssociationElement],
619603
diagnostics: &mut dyn DiagnosticHandler,
620604
) -> FatalNullResult {
621605
for AssociationElement { formal, actual } in elems.iter_mut() {
622606
if let Some(ref mut formal) = formal {
623-
self.resolve_formal_name(
607+
if let Err(err) = self.resolve_formal_name(
624608
formal_region,
625609
region,
626610
&formal.pos,
627611
&mut formal.item,
628612
diagnostics,
629-
)?;
613+
) {
614+
err.add_to(diagnostics)?;
615+
}
630616
}
631617
match actual.item {
632618
ActualPart::Expression(ref mut expr) => {

0 commit comments

Comments
 (0)