@@ -435,12 +435,17 @@ private predicate elementSpec(
435
435
}
436
436
437
437
/** Gets the fully templated version of `f`. */
438
- private Function getFullyTemplatedMemberFunction ( Function f ) {
438
+ private Function getFullyTemplatedFunction ( Function f ) {
439
439
not f .isFromUninstantiatedTemplate ( _) and
440
- exists ( Class c , Class templateClass , int i |
441
- c .isConstructedFrom ( templateClass ) and
442
- f = c .getAMember ( i ) and
443
- result = templateClass .getCanonicalMember ( i )
440
+ (
441
+ exists ( Class c , Class templateClass , int i |
442
+ c .isConstructedFrom ( templateClass ) and
443
+ f = c .getAMember ( i ) and
444
+ result = templateClass .getCanonicalMember ( i )
445
+ )
446
+ or
447
+ not exists ( f .getDeclaringType ( ) ) and
448
+ f .isConstructedFrom ( result )
444
449
)
445
450
}
446
451
@@ -464,14 +469,14 @@ string getParameterTypeWithoutTemplateArguments(Function f, int n) {
464
469
*/
465
470
private string getTypeNameWithoutFunctionTemplates ( Function f , int n , int remaining ) {
466
471
exists ( Function templateFunction |
467
- templateFunction = getFullyTemplatedMemberFunction ( f ) and
472
+ templateFunction = getFullyTemplatedFunction ( f ) and
468
473
remaining = templateFunction .getNumberOfTemplateArguments ( ) and
469
474
result = getParameterTypeWithoutTemplateArguments ( templateFunction , n )
470
475
)
471
476
or
472
477
exists ( string mid , TemplateParameter tp , Function templateFunction |
473
478
mid = getTypeNameWithoutFunctionTemplates ( f , n , remaining + 1 ) and
474
- templateFunction = getFullyTemplatedMemberFunction ( f ) and
479
+ templateFunction = getFullyTemplatedFunction ( f ) and
475
480
tp = templateFunction .getTemplateArgument ( remaining ) and
476
481
result = mid .replaceAll ( tp .getName ( ) , "func:" + remaining .toString ( ) )
477
482
)
@@ -482,12 +487,18 @@ private string getTypeNameWithoutFunctionTemplates(Function f, int n, int remain
482
487
* with `class:N` (where `N` is the index of the template).
483
488
*/
484
489
private string getTypeNameWithoutClassTemplates ( Function f , int n , int remaining ) {
490
+ // If there is a declaring type then we start by expanding the function templates
485
491
exists ( Class template |
486
492
f .getDeclaringType ( ) .isConstructedFrom ( template ) and
487
493
remaining = template .getNumberOfTemplateArguments ( ) and
488
494
result = getTypeNameWithoutFunctionTemplates ( f , n , 0 )
489
495
)
490
496
or
497
+ // If there is no declaring type we're done after expanding the function templates
498
+ not exists ( f .getDeclaringType ( ) ) and
499
+ remaining = 0 and
500
+ result = getTypeNameWithoutFunctionTemplates ( f , n , 0 )
501
+ or
491
502
exists ( string mid , TemplateParameter tp , Class template |
492
503
mid = getTypeNameWithoutClassTemplates ( f , n , remaining + 1 ) and
493
504
f .getDeclaringType ( ) .isConstructedFrom ( template ) and
@@ -750,17 +761,17 @@ private predicate elementSpecWithArguments0(
750
761
751
762
/**
752
763
* Holds if `elementSpec(namespace, type, subtypes, name, signature, _)` and
753
- * `method `'s signature matches `signature`.
764
+ * `func `'s signature matches `signature`.
754
765
*
755
766
* `signature` may contain template parameter names that are bound by `type` and `name`.
756
767
*/
757
768
pragma [ nomagic]
758
769
private predicate elementSpecMatchesSignature (
759
- Function method , string namespace , string type , boolean subtypes , string name , string signature
770
+ Function func , string namespace , string type , boolean subtypes , string name , string signature
760
771
) {
761
772
elementSpec ( namespace , pragma [ only_bind_into ] ( type ) , subtypes , pragma [ only_bind_into ] ( name ) ,
762
773
pragma [ only_bind_into ] ( signature ) , _) and
763
- signatureMatches ( method , signature , type , name , 0 )
774
+ signatureMatches ( func , signature , type , name , 0 )
764
775
}
765
776
766
777
/**
@@ -776,13 +787,22 @@ private predicate hasClassAndName(Class classWithMethod, Function method, string
776
787
)
777
788
}
778
789
790
+ bindingset [ name]
791
+ pragma [ inline_late]
792
+ private predicate funcHasQualifiedName ( Function func , string namespace , string name ) {
793
+ exists ( string nameWithoutArgs |
794
+ parseAngles ( name , nameWithoutArgs , _, "" ) and
795
+ func .hasQualifiedName ( namespace , name )
796
+ )
797
+ }
798
+
779
799
/**
780
800
* Holds if `namedClass` is in namespace `namespace` and has
781
801
* name `type` (excluding any template parameters).
782
802
*/
783
803
bindingset [ type, namespace]
784
804
pragma [ inline_late]
785
- private predicate hasQualifiedName ( Class namedClass , string namespace , string type ) {
805
+ private predicate classHasQualifiedName ( Class namedClass , string namespace , string type ) {
786
806
exists ( string typeWithoutArgs |
787
807
parseAngles ( type , typeWithoutArgs , _, "" ) and
788
808
namedClass .hasQualifiedName ( namespace , typeWithoutArgs )
@@ -804,15 +824,16 @@ private Element interpretElement0(
804
824
string namespace , string type , boolean subtypes , string name , string signature
805
825
) {
806
826
(
807
- elementSpec ( namespace , type , subtypes , name , signature , _) and
808
827
// Non-member functions
809
- exists ( Function func |
810
- func .hasQualifiedName ( namespace , name ) and
811
- type = "" and
812
- matchesSignature ( func , signature ) and
813
- subtypes = false and
814
- not exists ( func .getDeclaringType ( ) ) and
815
- result = func
828
+ elementSpec ( namespace , type , subtypes , name , signature , _) and
829
+ subtypes = false and
830
+ type = "" and
831
+ (
832
+ elementSpecMatchesSignature ( result , namespace , type , subtypes , name , signature )
833
+ or
834
+ signature = "" and
835
+ elementSpec ( namespace , type , subtypes , name , "" , _) and
836
+ funcHasQualifiedName ( result , namespace , name )
816
837
)
817
838
or
818
839
// Member functions
@@ -825,7 +846,7 @@ private Element interpretElement0(
825
846
elementSpec ( namespace , type , subtypes , name , "" , _) and
826
847
hasClassAndName ( classWithMethod , result , name )
827
848
) and
828
- hasQualifiedName ( namedClass , namespace , type ) and
849
+ classHasQualifiedName ( namedClass , namespace , type ) and
829
850
(
830
851
// member declared in the named type or a subtype of it
831
852
subtypes = true and
0 commit comments