@@ -130,6 +130,18 @@ private UserVariable getPotentialScopeOfVariable_candidate(UserVariable v) {
130
130
)
131
131
}
132
132
133
+ /** Gets a variable that is in the potential scope of variable `v`. */
134
+ private UserVariable getOuterScopesOfVariable_candidate ( UserVariable v ) {
135
+ exists ( Scope s |
136
+ result = s .getAVariable ( ) and
137
+ (
138
+ // Variable in an ancestor scope, but only if there are less than 100 variables in this scope
139
+ v = s .getAnAncestor ( ) .getAVariable ( ) and
140
+ s .getNumberOfVariables ( ) < 100
141
+ )
142
+ )
143
+ }
144
+
133
145
/** Holds if there exists a translation unit that includes both `f1` and `f2`. */
134
146
pragma [ noinline]
135
147
predicate inSameTranslationUnit ( File f1 , File f2 ) {
@@ -148,6 +160,15 @@ UserVariable getPotentialScopeOfVariable(UserVariable v) {
148
160
inSameTranslationUnit ( v .getFile ( ) , result .getFile ( ) )
149
161
}
150
162
163
+ /**
164
+ * Gets a user variable which occurs in the "outer scope" of variable `v`.
165
+ */
166
+ cached
167
+ UserVariable getPotentialScopeOfVariableStrict ( UserVariable v ) {
168
+ result = getOuterScopesOfVariable_candidate ( v ) and
169
+ inSameTranslationUnit ( v .getFile ( ) , result .getFile ( ) )
170
+ }
171
+
151
172
/** A file that is a C/C++ source file */
152
173
class SourceFile extends File {
153
174
SourceFile ( ) {
@@ -182,6 +203,15 @@ private predicate hides_candidate(UserVariable v1, UserVariable v2) {
182
203
not ( v1 .isMember ( ) or v2 .isMember ( ) )
183
204
}
184
205
206
+ /** Holds if `v2` may hide `v1`. */
207
+ private predicate hides_candidateStrict ( UserVariable v1 , UserVariable v2 ) {
208
+ not v1 = v2 and
209
+ v2 = getPotentialScopeOfVariableStrict ( 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
+
185
215
/** Holds if `v2` hides `v1`. */
186
216
predicate hides ( UserVariable v1 , UserVariable v2 ) {
187
217
hides_candidate ( v1 , v2 ) and
@@ -192,6 +222,16 @@ predicate hides(UserVariable v1, UserVariable v2) {
192
222
)
193
223
}
194
224
225
+ /** Holds if `v2` strictly (`v2` is in an inner scope compared to `v1`) hides `v1`. */
226
+ predicate hidesStrict ( UserVariable v1 , UserVariable v2 ) {
227
+ hides_candidateStrict ( v1 , v2 ) and
228
+ // Confirm that there's no closer candidate variable which `v2` hides
229
+ not exists ( UserVariable mid |
230
+ hides_candidateStrict ( v1 , mid ) and
231
+ hides_candidateStrict ( mid , v2 )
232
+ )
233
+ }
234
+
195
235
/** Holds if `decl` has namespace scope. */
196
236
predicate hasNamespaceScope ( Declaration decl ) {
197
237
// getNamespace always returns a namespace (e.g. the global namespace).
0 commit comments