@@ -435,12 +435,17 @@ private predicate elementSpec(
435435}
436436
437437/** Gets the fully templated version of `f`. */
438- private Function getFullyTemplatedMemberFunction ( Function f ) {
438+ private Function getFullyTemplatedFunction ( Function f ) {
439439 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 )
444449 )
445450}
446451
@@ -464,14 +469,14 @@ string getParameterTypeWithoutTemplateArguments(Function f, int n) {
464469 */
465470private string getTypeNameWithoutFunctionTemplates ( Function f , int n , int remaining ) {
466471 exists ( Function templateFunction |
467- templateFunction = getFullyTemplatedMemberFunction ( f ) and
472+ templateFunction = getFullyTemplatedFunction ( f ) and
468473 remaining = templateFunction .getNumberOfTemplateArguments ( ) and
469474 result = getParameterTypeWithoutTemplateArguments ( templateFunction , n )
470475 )
471476 or
472477 exists ( string mid , TemplateParameter tp , Function templateFunction |
473478 mid = getTypeNameWithoutFunctionTemplates ( f , n , remaining + 1 ) and
474- templateFunction = getFullyTemplatedMemberFunction ( f ) and
479+ templateFunction = getFullyTemplatedFunction ( f ) and
475480 tp = templateFunction .getTemplateArgument ( remaining ) and
476481 result = mid .replaceAll ( tp .getName ( ) , "func:" + remaining .toString ( ) )
477482 )
@@ -482,12 +487,18 @@ private string getTypeNameWithoutFunctionTemplates(Function f, int n, int remain
482487 * with `class:N` (where `N` is the index of the template).
483488 */
484489private string getTypeNameWithoutClassTemplates ( Function f , int n , int remaining ) {
490+ // If there is a declaring type then we start by expanding the function templates
485491 exists ( Class template |
486492 f .getDeclaringType ( ) .isConstructedFrom ( template ) and
487493 remaining = template .getNumberOfTemplateArguments ( ) and
488494 result = getTypeNameWithoutFunctionTemplates ( f , n , 0 )
489495 )
490496 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
491502 exists ( string mid , TemplateParameter tp , Class template |
492503 mid = getTypeNameWithoutClassTemplates ( f , n , remaining + 1 ) and
493504 f .getDeclaringType ( ) .isConstructedFrom ( template ) and
@@ -750,17 +761,17 @@ private predicate elementSpecWithArguments0(
750761
751762/**
752763 * Holds if `elementSpec(namespace, type, subtypes, name, signature, _)` and
753- * `method `'s signature matches `signature`.
764+ * `func `'s signature matches `signature`.
754765 *
755766 * `signature` may contain template parameter names that are bound by `type` and `name`.
756767 */
757768pragma [ nomagic]
758769private 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
760771) {
761772 elementSpec ( namespace , pragma [ only_bind_into ] ( type ) , subtypes , pragma [ only_bind_into ] ( name ) ,
762773 pragma [ only_bind_into ] ( signature ) , _) and
763- signatureMatches ( method , signature , type , name , 0 )
774+ signatureMatches ( func , signature , type , name , 0 )
764775}
765776
766777/**
@@ -776,13 +787,22 @@ private predicate hasClassAndName(Class classWithMethod, Function method, string
776787 )
777788}
778789
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+
779799/**
780800 * Holds if `namedClass` is in namespace `namespace` and has
781801 * name `type` (excluding any template parameters).
782802 */
783803bindingset [ type, namespace]
784804pragma [ inline_late]
785- private predicate hasQualifiedName ( Class namedClass , string namespace , string type ) {
805+ private predicate classHasQualifiedName ( Class namedClass , string namespace , string type ) {
786806 exists ( string typeWithoutArgs |
787807 parseAngles ( type , typeWithoutArgs , _, "" ) and
788808 namedClass .hasQualifiedName ( namespace , typeWithoutArgs )
@@ -804,15 +824,16 @@ private Element interpretElement0(
804824 string namespace , string type , boolean subtypes , string name , string signature
805825) {
806826 (
807- elementSpec ( namespace , type , subtypes , name , signature , _) and
808827 // 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 )
816837 )
817838 or
818839 // Member functions
@@ -825,7 +846,7 @@ private Element interpretElement0(
825846 elementSpec ( namespace , type , subtypes , name , "" , _) and
826847 hasClassAndName ( classWithMethod , result , name )
827848 ) and
828- hasQualifiedName ( namedClass , namespace , type ) and
849+ classHasQualifiedName ( namedClass , namespace , type ) and
829850 (
830851 // member declared in the named type or a subtype of it
831852 subtypes = true and
0 commit comments