@@ -474,6 +474,15 @@ pub enum StatementAnnotation {
474
474
/// The call name of the function iff it differs from the qualified name (generics)
475
475
call_name : Option < String > ,
476
476
} ,
477
+ FunctionPointer {
478
+ /// The defined return type of the function
479
+ return_type : String ,
480
+ /// The defined qualified name of the function
481
+ qualified_name : String ,
482
+ // TODO: Is this needed?
483
+ // The call name of the function iff it differs from the qualified name (generics)
484
+ // call_name: Option<String>,
485
+ } ,
477
486
/// a reference to a type (e.g. `INT`)
478
487
Type {
479
488
type_name : String ,
@@ -676,6 +685,17 @@ impl StatementAnnotation {
676
685
StatementAnnotation :: Value { resulting_type : type_name. into ( ) }
677
686
}
678
687
688
+ pub fn fnptr < T , U > ( return_ty : T , qualified_name : U ) -> Self
689
+ where
690
+ T : Into < String > ,
691
+ U : Into < String > ,
692
+ {
693
+ StatementAnnotation :: FunctionPointer {
694
+ return_type : return_ty. into ( ) ,
695
+ qualified_name : qualified_name. into ( ) ,
696
+ }
697
+ }
698
+
679
699
pub fn create_override ( definitions : Vec < MethodDeclarationType > ) -> Self {
680
700
StatementAnnotation :: Override { definitions }
681
701
}
@@ -721,6 +741,10 @@ impl StatementAnnotation {
721
741
matches ! ( self , StatementAnnotation :: Property { .. } )
722
742
}
723
743
744
+ pub fn is_fnptr ( & self ) -> bool {
745
+ matches ! ( self , StatementAnnotation :: FunctionPointer { .. } )
746
+ }
747
+
724
748
pub fn qualified_name ( & self ) -> Option < & str > {
725
749
match self {
726
750
StatementAnnotation :: Variable { qualified_name, .. }
@@ -851,6 +875,7 @@ pub trait AnnotationMap {
851
875
| StatementAnnotation :: Super { name : qualified_name, .. } => Some ( qualified_name. as_str ( ) ) ,
852
876
StatementAnnotation :: Type { type_name } => Some ( type_name) ,
853
877
StatementAnnotation :: Function { qualified_name, .. } => Some ( qualified_name) ,
878
+ StatementAnnotation :: FunctionPointer { qualified_name, .. } => Some ( qualified_name) ,
854
879
StatementAnnotation :: Label { .. }
855
880
| StatementAnnotation :: Override { .. }
856
881
| StatementAnnotation :: MethodDeclarations { .. }
@@ -2029,12 +2054,15 @@ impl<'i> TypeAnnotator<'i> {
2029
2054
. find_effective_type_by_name ( inner_type_name)
2030
2055
. or ( self . annotation_map . new_index . find_effective_type_by_name ( inner_type_name) )
2031
2056
{
2032
- // TODO(vosa): also add is_method() check
2033
2057
// We're dealing with a function pointer, hence annotate the deref node with the variables name
2034
- if inner_type. get_type_information ( ) . is_function ( )
2035
- || inner_type. get_type_information ( ) . is_method ( )
2036
- {
2037
- self . annotate ( stmt, StatementAnnotation :: value ( name) ) ;
2058
+ // XXX: Functions are intentionally ignored here for now, as the feature as of writing
2059
+ // this comment is only interesting for methods due to polymorphism.
2060
+ if inner_type. get_type_information ( ) . is_method ( ) {
2061
+ let pou = self . index . find_pou ( & inner_type. name ) . unwrap ( ) ;
2062
+ self . annotate (
2063
+ stmt,
2064
+ StatementAnnotation :: fnptr ( pou. get_return_type ( ) . unwrap ( ) , pou. get_name ( ) ) ,
2065
+ )
2038
2066
} else {
2039
2067
self . annotate ( stmt, StatementAnnotation :: value ( inner_type. get_name ( ) ) )
2040
2068
}
@@ -2223,6 +2251,9 @@ impl<'i> TypeAnnotator<'i> {
2223
2251
StatementAnnotation :: Function { qualified_name, call_name, .. } => {
2224
2252
call_name. as_ref ( ) . cloned ( ) . or_else ( || Some ( qualified_name. clone ( ) ) )
2225
2253
}
2254
+ StatementAnnotation :: FunctionPointer { qualified_name, .. } => {
2255
+ Some ( qualified_name. to_string ( ) )
2256
+ }
2226
2257
StatementAnnotation :: Program { qualified_name } => Some ( qualified_name. clone ( ) ) ,
2227
2258
StatementAnnotation :: Variable { resulting_type, .. } => self
2228
2259
. index
@@ -2243,24 +2274,7 @@ impl<'i> TypeAnnotator<'i> {
2243
2274
AstStatement :: ReferenceExpr (
2244
2275
ReferenceExpr { access : ReferenceAccess :: Deref , .. } ,
2245
2276
..,
2246
- ) => {
2247
- let mut resulting_type = resulting_type. to_string ( ) ;
2248
-
2249
- // When dealing with a pointer, we have to fetch the target type
2250
- if let Some ( DataTypeInformation :: Pointer { inner_type_name, .. } ) = self
2251
- . index
2252
- . find_effective_type_by_name ( & resulting_type)
2253
- . map ( |opt| opt. get_type_information ( ) )
2254
- {
2255
- resulting_type = self
2256
- . index
2257
- . find_pou ( inner_type_name)
2258
- . map ( |opt| opt. get_name ( ) . to_string ( ) )
2259
- . expect ( "must exist" )
2260
- }
2261
-
2262
- self . index . find_pou ( resulting_type. as_str ( ) ) . map ( |it| it. get_name ( ) . to_string ( ) )
2263
- }
2277
+ ) => self . index . find_pou ( resulting_type. as_str ( ) ) . map ( |it| it. get_name ( ) . to_string ( ) ) ,
2264
2278
2265
2279
_ => None ,
2266
2280
}
0 commit comments