11import semmle.code.cpp.Type
22
3- /** Holds if `d` is a complete class named `name`. */
3+ pragma [ noinline]
4+ private string getTopLevelClassName ( @usertype c ) {
5+ isClass ( c ) and
6+ usertypes ( c , result , _) and
7+ not namespacembrs ( _, c ) and // not in a namespace
8+ not member ( _, _, c ) and // not in some structure
9+ not class_instantiation ( c , _) // not a template instantiation
10+ }
11+
12+ /** Holds if `d` is a unique complete class named `name`. */
413pragma [ noinline]
514private predicate existsCompleteWithName ( string name , @usertype d ) {
6- isClass ( d ) and
715 is_complete ( d ) and
8- usertypes ( d , name , _)
16+ name = getTopLevelClassName ( d ) and
17+ strictcount ( @usertype other | is_complete ( other ) and getTopLevelClassName ( other ) = name ) = 1
918}
1019
1120/** Holds if `c` is an incomplete class named `name`. */
1221pragma [ noinline]
1322private predicate existsIncompleteWithName ( string name , @usertype c ) {
14- isClass ( c ) and
1523 not is_complete ( c ) and
16- usertypes ( c , name , _ )
24+ name = getTopLevelClassName ( c )
1725}
1826
1927/**
20- * Holds if `c` is an imcomplete class, and there exists a complete class `d`
28+ * Holds if `c` is an imcomplete class, and there exists a unique complete class `d`
2129 * with the same name.
2230 */
2331private predicate hasCompleteTwin ( @usertype c , @usertype d ) {
@@ -30,10 +38,8 @@ private predicate hasCompleteTwin(@usertype c, @usertype d) {
3038import Cached
3139cached private module Cached {
3240 /**
33- * If `c` is incomplete, and there exists a complete class with the same name,
34- * then the result is that complete class. Otherwise, the result is `c`. If
35- * multiple complete classes have the same name, this predicate may have
36- * multiple results.
41+ * If `c` is incomplete, and there exists a unique complete class with the same name,
42+ * then the result is that complete class. Otherwise, the result is `c`.
3743 */
3844 cached @usertype resolveClass ( @usertype c ) {
3945 hasCompleteTwin ( c , result )
0 commit comments