@@ -141,7 +141,7 @@ impl<'a> AnalyzeContext<'a> {
141141 match resolved_name {
142142 ResolvedName :: ObjectName ( oname) => {
143143 if let Some ( ref signature) = signature {
144- diagnostics. push ( signature_error ( signature) ) ;
144+ diagnostics. push ( Diagnostic :: should_not_have_signature ( "Alias" , signature) ) ;
145145 }
146146 match oname. base {
147147 ObjectBase :: Object ( base_object) => AnyEntKind :: ObjectAlias {
@@ -166,7 +166,7 @@ impl<'a> AnalyzeContext<'a> {
166166 | ResolvedName :: Design ( _)
167167 | ResolvedName :: Expression ( _) => {
168168 if let Some ( ref signature) = signature {
169- diagnostics. push ( signature_error ( signature) ) ;
169+ diagnostics. push ( Diagnostic :: should_not_have_signature ( "Alias" , signature) ) ;
170170 }
171171 diagnostics. error (
172172 & name. pos ,
@@ -176,7 +176,7 @@ impl<'a> AnalyzeContext<'a> {
176176 }
177177 ResolvedName :: Type ( typ) => {
178178 if let Some ( ref signature) = signature {
179- diagnostics. push ( signature_error ( signature) ) ;
179+ diagnostics. push ( Diagnostic :: should_not_have_signature ( "Alias" , signature) ) ;
180180 }
181181 AnyEntKind :: Type ( Type :: Alias ( typ) )
182182 }
@@ -190,22 +190,11 @@ impl<'a> AnalyzeContext<'a> {
190190 }
191191 AnyEntKind :: Overloaded ( Overloaded :: Alias ( ent) )
192192 } else {
193- let mut diagnostic = Diagnostic :: error (
194- name,
195- format ! (
196- "Could not find declaration of {} with given signature" ,
197- des. item. describe( )
198- ) ,
199- ) ;
200- for ent in overloaded. entities ( ) {
201- if let Some ( pos) = ent. decl_pos ( ) {
202- diagnostic. add_related (
203- pos,
204- format ! ( "Found {}" , ent. describe( ) ) ,
205- ) ;
206- }
207- }
208- diagnostics. push ( diagnostic) ;
193+ diagnostics. push ( Diagnostic :: no_overloaded_with_signature (
194+ & des. pos ,
195+ & des. item ,
196+ & overloaded,
197+ ) ) ;
209198 return Ok ( None ) ;
210199 }
211200 }
@@ -215,10 +204,7 @@ impl<'a> AnalyzeContext<'a> {
215204 }
216205 }
217206 } else {
218- diagnostics. error (
219- name,
220- "Signature required for alias of subprogram and enum literals" ,
221- ) ;
207+ diagnostics. push ( Diagnostic :: signature_required ( name) ) ;
222208 return Ok ( None ) ;
223209 }
224210 }
@@ -350,17 +336,107 @@ impl<'a> AnalyzeContext<'a> {
350336 }
351337 Declaration :: Attribute ( ref mut attr) => match attr {
352338 Attribute :: Declaration ( ref mut attr_decl) => {
353- if let Err ( err) = self . resolve_type_mark ( scope, & mut attr_decl. type_mark ) {
354- err. add_to ( diagnostics) ?;
339+ match self . resolve_type_mark ( scope, & mut attr_decl. type_mark ) {
340+ Ok ( typ) => {
341+ scope. add (
342+ self . arena
343+ . define ( & mut attr_decl. ident , AnyEntKind :: Attribute ( typ) ) ,
344+ diagnostics,
345+ ) ;
346+ }
347+ Err ( err) => {
348+ err. add_to ( diagnostics) ?;
349+ }
355350 }
356- scope. add (
357- self . arena
358- . define ( & mut attr_decl. ident , AnyEntKind :: Attribute ) ,
359- diagnostics,
360- ) ;
361351 }
362352 // @TODO Ignored for now
363- Attribute :: Specification ( ..) => { }
353+ Attribute :: Specification ( ref mut attr_spec) => {
354+ let AttributeSpecification {
355+ ident,
356+ entity_name,
357+ // @TODO also check the entity class
358+ entity_class : _,
359+ expr,
360+ } = attr_spec;
361+
362+ match scope. lookup (
363+ & ident. item . pos ,
364+ & Designator :: Identifier ( ident. item . name ( ) . clone ( ) ) ,
365+ ) {
366+ Ok ( NamedEntities :: Single ( ent) ) => {
367+ ident. set_unique_reference ( ent) ;
368+ if let AnyEntKind :: Attribute ( typ) = ent. actual_kind ( ) {
369+ self . analyze_expression_with_target_type (
370+ scope,
371+ * typ,
372+ & expr. pos ,
373+ & mut expr. item ,
374+ diagnostics,
375+ ) ?;
376+ } else {
377+ diagnostics. error (
378+ & ident. item . pos ,
379+ format ! ( "{} is not an attribute" , ent. describe( ) ) ,
380+ ) ;
381+ }
382+ }
383+ Ok ( NamedEntities :: Overloaded ( _) ) => {
384+ diagnostics. error (
385+ & ident. item . pos ,
386+ format ! ( "Overloaded name '{}' is not an attribute" , ident. item) ,
387+ ) ;
388+ }
389+ Err ( err) => {
390+ diagnostics. push ( err) ;
391+ }
392+ }
393+
394+ if let EntityName :: Name ( EntityTag {
395+ designator,
396+ signature,
397+ } ) = entity_name
398+ {
399+ match scope. lookup ( & designator. pos , & designator. item . item ) {
400+ Ok ( NamedEntities :: Single ( ent) ) => {
401+ designator. set_unique_reference ( ent) ;
402+
403+ if let Some ( signature) = signature {
404+ diagnostics. push ( Diagnostic :: should_not_have_signature (
405+ "Attribute specification" ,
406+ & signature. pos ,
407+ ) ) ;
408+ }
409+ }
410+ Ok ( NamedEntities :: Overloaded ( overloaded) ) => {
411+ if let Some ( signature) = signature {
412+ match self . resolve_signature ( scope, signature) {
413+ Ok ( signature_key) => {
414+ if let Some ( ent) = overloaded. get ( & signature_key) {
415+ designator. set_unique_reference ( & ent) ;
416+ } else {
417+ diagnostics. push (
418+ Diagnostic :: no_overloaded_with_signature (
419+ & designator. pos ,
420+ & designator. item . item ,
421+ & overloaded,
422+ ) ,
423+ ) ;
424+ }
425+ }
426+ Err ( err) => {
427+ err. add_to ( diagnostics) ?;
428+ }
429+ }
430+ } else {
431+ diagnostics. push ( Diagnostic :: signature_required ( designator) ) ;
432+ }
433+ }
434+ Err ( err) => {
435+ diagnostics. push ( err) ;
436+ }
437+ }
438+ }
439+ }
364440 } ,
365441 Declaration :: SubprogramBody ( ref mut body) => {
366442 let subpgm_region = scope. nested ( ) ;
@@ -1119,11 +1195,39 @@ fn find_full_type_definition<'a>(
11191195 None
11201196}
11211197
1122- fn signature_error ( pos : impl AsRef < SrcPos > ) -> Diagnostic {
1123- Diagnostic :: error (
1124- pos,
1125- "Alias should only have a signature for subprograms and enum literals" ,
1126- )
1198+ impl Diagnostic {
1199+ fn no_overloaded_with_signature (
1200+ pos : & SrcPos ,
1201+ des : & Designator ,
1202+ overloaded : & OverloadedName ,
1203+ ) -> Diagnostic {
1204+ let mut diagnostic = Diagnostic :: error (
1205+ pos,
1206+ format ! (
1207+ "Could not find declaration of {} with given signature" ,
1208+ des. describe( )
1209+ ) ,
1210+ ) ;
1211+ diagnostic. add_subprogram_candidates ( "Found" , overloaded. entities ( ) ) ;
1212+ diagnostic
1213+ }
1214+
1215+ fn should_not_have_signature ( prefix : & str , pos : impl AsRef < SrcPos > ) -> Diagnostic {
1216+ Diagnostic :: error (
1217+ pos,
1218+ format ! (
1219+ "{} should only have a signature for subprograms and enum literals" ,
1220+ prefix
1221+ ) ,
1222+ )
1223+ }
1224+
1225+ fn signature_required ( pos : impl AsRef < SrcPos > ) -> Diagnostic {
1226+ Diagnostic :: error (
1227+ pos,
1228+ "Signature required for alias of subprogram and enum literals" ,
1229+ )
1230+ }
11271231}
11281232
11291233/// @TODO A simple and incomplete way to disambiguate integer and real in standard.vhd
0 commit comments