@@ -57,10 +57,18 @@ private Element getParentScope(Element e) {
57
57
58
58
/** A variable which is defined by the user, rather than being from a third party or compiler generated. */
59
59
class UserVariable extends Variable {
60
- UserVariable ( ) {
60
+ UserVariable ( ) { this instanceof UserDeclaration }
61
+ }
62
+
63
+ /** A construct which is defined by the user, rather than being from a third party or compiler generated. */
64
+ class UserDeclaration extends Declaration {
65
+ UserDeclaration ( ) {
61
66
exists ( getFile ( ) .getRelativePath ( ) ) and
62
- not isCompilerGenerated ( ) and
67
+ not this .( Variable ) .isCompilerGenerated ( ) and
68
+ not this .( Function ) .isCompilerGenerated ( ) and
63
69
not this .( Parameter ) .getFunction ( ) .isCompilerGenerated ( ) and
70
+ // Class template instantiations are compiler generated instances that share the same parent scope. This will result in a cross-product on class template instantiations because they have the same name and same parent scope. We therefore exclude these from consideration like we do with other compiler generated identifiers of interest.
71
+ not this instanceof ClassTemplateInstantiation and
64
72
// compiler inferred parameters have name of p#0
65
73
not this .( Parameter ) .getName ( ) = "p#0"
66
74
}
@@ -74,11 +82,13 @@ class Scope extends Element {
74
82
75
83
int getNumberOfVariables ( ) { result = count ( getAVariable ( ) ) }
76
84
85
+ int getNumberOfDeclarations ( ) { result = count ( getADeclaration ( ) ) }
86
+
77
87
Scope getAnAncestor ( ) { result = this .getStrictParent + ( ) }
78
88
79
89
Scope getStrictParent ( ) { result = getParentScope ( this ) }
80
90
81
- Declaration getADeclaration ( ) { getParentScope ( result ) = this }
91
+ UserDeclaration getADeclaration ( ) { getParentScope ( result ) = this }
82
92
83
93
Expr getAnExpr ( ) { this = getParentScope ( result ) }
84
94
@@ -122,31 +132,31 @@ class GeneratedBlockStmt extends BlockStmt {
122
132
GeneratedBlockStmt ( ) { this .getLocation ( ) instanceof UnknownLocation }
123
133
}
124
134
125
- /** Gets a variable that is in the potential scope of variable `v`. */
126
- private UserVariable getPotentialScopeOfVariable_candidate ( UserVariable v ) {
135
+ /** Gets a Declaration that is in the potential scope of Declaration `v`. */
136
+ private UserDeclaration getPotentialScopeOfDeclaration_candidate ( UserDeclaration v ) {
127
137
exists ( Scope s |
128
- result = s .getAVariable ( ) and
138
+ result = s .getADeclaration ( ) and
129
139
(
130
- // Variable in an ancestor scope, but only if there are less than 100 variables in this scope
131
- v = s .getAnAncestor ( ) .getAVariable ( ) and
132
- s .getNumberOfVariables ( ) < 100
140
+ // Declaration in an ancestor scope, but only if there are less than 100 declarations in this scope
141
+ v = s .getAnAncestor ( ) .getADeclaration ( ) and
142
+ s .getNumberOfDeclarations ( ) < 100
133
143
or
134
- // In the same scope, but not the same variable , and choose just one to report
135
- v = s .getAVariable ( ) and
144
+ // In the same scope, but not the same Declaration , and choose just one to report
145
+ v = s .getADeclaration ( ) and
136
146
not result = v and
137
147
v .getName ( ) <= result .getName ( )
138
148
)
139
149
)
140
150
}
141
151
142
- /** Gets a variable that is in the potential scope of variable `v`. */
143
- private UserVariable getOuterScopesOfVariable_candidate ( UserVariable v ) {
152
+ /** Gets a Declaration that is in the potential scope of Declaration `v`. */
153
+ private UserDeclaration getPotentialScopeOfDeclarationStrict_candidate ( UserDeclaration v ) {
144
154
exists ( Scope s |
145
- result = s .getAVariable ( ) and
155
+ result = s .getADeclaration ( ) and
146
156
(
147
- // Variable in an ancestor scope, but only if there are less than 100 variables in this scope
148
- v = s .getAnAncestor ( ) .getAVariable ( ) and
149
- s .getNumberOfVariables ( ) < 100
157
+ // Declaration in an ancestor scope, but only if there are less than 100 variables in this scope
158
+ v = s .getAnAncestor ( ) .getADeclaration ( ) and
159
+ s .getNumberOfDeclarations ( ) < 100
150
160
)
151
161
)
152
162
}
@@ -161,20 +171,20 @@ predicate inSameTranslationUnit(File f1, File f2) {
161
171
}
162
172
163
173
/**
164
- * Gets a user variable which occurs in the "potential scope" of variable `v`.
174
+ * Gets a user Declaration which occurs in the "outer scope" of Declaration `v`.
165
175
*/
166
176
cached
167
- UserVariable getPotentialScopeOfVariable ( UserVariable v ) {
168
- result = getPotentialScopeOfVariable_candidate ( v ) and
177
+ UserDeclaration getPotentialScopeOfDeclarationStrict ( UserDeclaration v ) {
178
+ result = getPotentialScopeOfDeclarationStrict_candidate ( v ) and
169
179
inSameTranslationUnit ( v .getFile ( ) , result .getFile ( ) )
170
180
}
171
181
172
182
/**
173
- * Gets a user variable which occurs in the "outer scope" of variable `v`.
183
+ * Gets a user variable which occurs in the "potential scope" of variable `v`.
174
184
*/
175
185
cached
176
- UserVariable getPotentialScopeOfVariableStrict ( UserVariable v ) {
177
- result = getOuterScopesOfVariable_candidate ( v ) and
186
+ UserDeclaration getPotentialScopeOfDeclaration ( UserDeclaration v ) {
187
+ result = getPotentialScopeOfDeclaration_candidate ( v ) and
178
188
inSameTranslationUnit ( v .getFile ( ) , result .getFile ( ) )
179
189
}
180
190
@@ -204,18 +214,9 @@ class TranslationUnit extends SourceFile {
204
214
}
205
215
206
216
/** Holds if `v2` may hide `v1`. */
207
- private predicate hides_candidate ( UserVariable v1 , UserVariable v2 ) {
217
+ private predicate hides_candidateStrict ( UserDeclaration v1 , UserDeclaration v2 ) {
208
218
not v1 = v2 and
209
- v2 = getPotentialScopeOfVariable ( v1 ) and
210
- v1 .getName ( ) = v2 .getName ( ) and
211
- // Member variables cannot hide other variables nor be hidden because the can be referenced through their qualified name.
212
- not ( v1 .isMember ( ) or v2 .isMember ( ) )
213
- }
214
-
215
- /** Holds if `v2` may hide `v1`. */
216
- private predicate hides_candidateStrict ( UserVariable v1 , UserVariable v2 ) {
217
- not v1 = v2 and
218
- v2 = getPotentialScopeOfVariableStrict ( v1 ) and
219
+ v2 = getPotentialScopeOfDeclarationStrict ( v1 ) and
219
220
v1 .getName ( ) = v2 .getName ( ) and
220
221
// Member variables cannot hide other variables nor be hidden because the can be referenced through their qualified name.
221
222
not ( v1 .isMember ( ) or v2 .isMember ( ) ) and
@@ -239,6 +240,15 @@ private predicate hides_candidateStrict(UserVariable v1, UserVariable v2) {
239
240
)
240
241
}
241
242
243
+ /** Holds if `v2` may hide `v1`. */
244
+ private predicate hides_candidate ( UserDeclaration v1 , UserDeclaration v2 ) {
245
+ not v1 = v2 and
246
+ v2 = getPotentialScopeOfDeclaration ( v1 ) and
247
+ v1 .getName ( ) = v2 .getName ( ) and
248
+ // Member variables cannot hide other variables nor be hidden because the can be referenced through their qualified name.
249
+ not ( v1 .isMember ( ) or v2 .isMember ( ) )
250
+ }
251
+
242
252
/**
243
253
* Gets the enclosing statement of the given variable, if any.
244
254
*/
@@ -257,20 +267,22 @@ private Stmt getEnclosingStmt(LocalScopeVariable v) {
257
267
}
258
268
259
269
/** Holds if `v2` hides `v1`. */
260
- predicate hides ( UserVariable v1 , UserVariable v2 ) {
270
+ predicate hides ( UserDeclaration v1 , UserDeclaration v2 ) {
261
271
hides_candidate ( v1 , v2 ) and
262
272
// Confirm that there's no closer candidate variable which `v2` hides
263
- not exists ( UserVariable mid |
273
+ not exists ( UserDeclaration mid |
264
274
hides_candidate ( v1 , mid ) and
265
275
hides_candidate ( mid , v2 )
266
- )
276
+ ) and
277
+ // Unlike `hidesStrict`, that requires a different scope, `hides` considers declarations in the same scope. This will include function overloads based on their name. To remove overloads from consideration, we exclude them.
278
+ not v1 .( Function ) .getAnOverload ( ) = v2
267
279
}
268
280
269
281
/** Holds if `v2` strictly (`v2` is in an inner scope compared to `v1`) hides `v1`. */
270
- predicate hidesStrict ( UserVariable v1 , UserVariable v2 ) {
282
+ predicate hidesStrict ( UserDeclaration v1 , UserDeclaration v2 ) {
271
283
hides_candidateStrict ( v1 , v2 ) and
272
284
// Confirm that there's no closer candidate variable which `v2` hides
273
- not exists ( UserVariable mid |
285
+ not exists ( UserDeclaration mid |
274
286
hides_candidateStrict ( v1 , mid ) and
275
287
hides_candidateStrict ( mid , v2 )
276
288
)
@@ -287,3 +299,18 @@ predicate hasClassScope(Declaration decl) { exists(decl.getDeclaringType()) }
287
299
288
300
/** Holds if `decl` has block scope. */
289
301
predicate hasBlockScope ( Declaration decl ) { exists ( BlockStmt b | b .getADeclaration ( ) = decl ) }
302
+
303
+ /**
304
+ * identifiers in nested (named/nonglobal) namespaces are exceptions to hiding due to being able access via fully qualified ids
305
+ */
306
+ predicate excludedViaNestedNamespaces ( UserDeclaration outerDecl , UserDeclaration innerDecl ) {
307
+ exists ( Namespace inner , Namespace outer |
308
+ outer .getAChildNamespace + ( ) = inner and
309
+ //outer is not global
310
+ not outer instanceof GlobalNamespace and
311
+ not outer .isAnonymous ( ) and
312
+ not inner .isAnonymous ( ) and
313
+ innerDecl .getNamespace ( ) = inner and
314
+ outerDecl .getNamespace ( ) = outer
315
+ )
316
+ }
0 commit comments