@@ -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
@@ -570,38 +581,6 @@ private string getSignatureWithoutFunctionTemplateNames(
570
581
)
571
582
}
572
583
573
- private string paramsStringPart ( Function c , int i ) {
574
- not c .isFromUninstantiatedTemplate ( _) and
575
- (
576
- i = - 1 and result = "(" and exists ( c )
577
- or
578
- exists ( int n , string p | getParameterTypeName ( c , n ) = p |
579
- i = 2 * n and result = p
580
- or
581
- i = 2 * n - 1 and result = "," and n != 0
582
- )
583
- or
584
- i = 2 * c .getNumberOfParameters ( ) and result = ")"
585
- )
586
- }
587
-
588
- /**
589
- * Gets a parenthesized string containing all parameter types of this callable, separated by a comma.
590
- *
591
- * Returns the empty string if the callable has no parameters.
592
- * Parameter types are represented by their type erasure.
593
- */
594
- cached
595
- private string paramsString ( Function c ) {
596
- result = concat ( int i | | paramsStringPart ( c , i ) order by i )
597
- }
598
-
599
- bindingset [ func]
600
- private predicate matchesSignature ( Function func , string signature ) {
601
- signature = "" or
602
- paramsString ( func ) = signature
603
- }
604
-
605
584
/**
606
585
* Holds if `elementSpec(_, type, _, name, signature, _)` holds and
607
586
* - `typeArgs` represents the named template parameters supplied to `type`, and
@@ -750,17 +729,17 @@ private predicate elementSpecWithArguments0(
750
729
751
730
/**
752
731
* Holds if `elementSpec(namespace, type, subtypes, name, signature, _)` and
753
- * `method `'s signature matches `signature`.
732
+ * `func `'s signature matches `signature`.
754
733
*
755
734
* `signature` may contain template parameter names that are bound by `type` and `name`.
756
735
*/
757
736
pragma [ nomagic]
758
737
private predicate elementSpecMatchesSignature (
759
- Function method , string namespace , string type , boolean subtypes , string name , string signature
738
+ Function func , string namespace , string type , boolean subtypes , string name , string signature
760
739
) {
761
740
elementSpec ( namespace , pragma [ only_bind_into ] ( type ) , subtypes , pragma [ only_bind_into ] ( name ) ,
762
741
pragma [ only_bind_into ] ( signature ) , _) and
763
- signatureMatches ( method , signature , type , name , 0 )
742
+ signatureMatches ( func , signature , type , name , 0 )
764
743
}
765
744
766
745
/**
@@ -776,13 +755,22 @@ private predicate hasClassAndName(Class classWithMethod, Function method, string
776
755
)
777
756
}
778
757
758
+ bindingset [ name]
759
+ pragma [ inline_late]
760
+ private predicate funcHasQualifiedName ( Function func , string namespace , string name ) {
761
+ exists ( string nameWithoutArgs |
762
+ parseAngles ( name , nameWithoutArgs , _, "" ) and
763
+ func .hasQualifiedName ( namespace , nameWithoutArgs )
764
+ )
765
+ }
766
+
779
767
/**
780
768
* Holds if `namedClass` is in namespace `namespace` and has
781
769
* name `type` (excluding any template parameters).
782
770
*/
783
771
bindingset [ type, namespace]
784
772
pragma [ inline_late]
785
- private predicate hasQualifiedName ( Class namedClass , string namespace , string type ) {
773
+ private predicate classHasQualifiedName ( Class namedClass , string namespace , string type ) {
786
774
exists ( string typeWithoutArgs |
787
775
parseAngles ( type , typeWithoutArgs , _, "" ) and
788
776
namedClass .hasQualifiedName ( namespace , typeWithoutArgs )
@@ -804,15 +792,16 @@ private Element interpretElement0(
804
792
string namespace , string type , boolean subtypes , string name , string signature
805
793
) {
806
794
(
807
- elementSpec ( namespace , type , subtypes , name , signature , _) and
808
795
// 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
796
+ elementSpec ( namespace , type , subtypes , name , signature , _) and
797
+ subtypes = false and
798
+ type = "" and
799
+ (
800
+ elementSpecMatchesSignature ( result , namespace , type , subtypes , name , signature )
801
+ or
802
+ signature = "" and
803
+ elementSpec ( namespace , type , subtypes , name , "" , _) and
804
+ funcHasQualifiedName ( result , namespace , name )
816
805
)
817
806
or
818
807
// Member functions
@@ -825,7 +814,7 @@ private Element interpretElement0(
825
814
elementSpec ( namespace , type , subtypes , name , "" , _) and
826
815
hasClassAndName ( classWithMethod , result , name )
827
816
) and
828
- hasQualifiedName ( namedClass , namespace , type ) and
817
+ classHasQualifiedName ( namedClass , namespace , type ) and
829
818
(
830
819
// member declared in the named type or a subtype of it
831
820
subtypes = true and
0 commit comments