@@ -78,6 +78,14 @@ class Scope extends Element {
78
78
79
79
UserVariable getAVariable ( ) { Internal:: getParentScope ( result ) = this }
80
80
81
+ /**
82
+ * Gets the `Variable` with the given `name` that is declared in this scope.
83
+ */
84
+ UserVariable getVariable ( string name ) {
85
+ result = getAVariable ( ) and
86
+ result .getName ( ) = name
87
+ }
88
+
81
89
int getNumberOfVariables ( ) { result = count ( getAVariable ( ) ) }
82
90
83
91
Scope getAnAncestor ( ) { result = this .getStrictParent + ( ) }
@@ -152,9 +160,9 @@ class Scope extends Element {
152
160
}
153
161
154
162
/**
155
- * Gets a variable with `name` which is hidden in at least one nested scope.
163
+ * Gets a variable with `name` which is potentially hidden in at least one nested scope.
156
164
*/
157
- UserVariable getAHiddenVariable ( string name ) {
165
+ private UserVariable getAPotentiallyHiddenVariable ( string name ) {
158
166
result = getAVariable ( ) and
159
167
result .getName ( ) = name and
160
168
isDeclaredNameHiddenByChild ( name )
@@ -163,34 +171,43 @@ class Scope extends Element {
163
171
/**
164
172
* Holds if `name` is declared above this scope and hidden by this or a nested scope.
165
173
*/
166
- private predicate isNameDeclaredAboveHiddenByThisOrNested ( string name ) {
167
- (
168
- this . getStrictParent ( ) . isDeclaredNameHiddenByChild ( name ) or
169
- this . getStrictParent ( ) . isNameDeclaredAboveHiddenByThisOrNested ( name )
174
+ UserVariable getAVariableHiddenByThisOrNestedScope ( string name ) {
175
+ exists ( Scope parent | parent = this . getStrictParent ( ) |
176
+ result = parent . getAPotentiallyHiddenVariable ( name ) or
177
+ result = parent . getAVariableHiddenByThisOrNestedScope ( name )
170
178
) and
171
179
isNameDeclaredInThisOrNestedScope ( name )
172
180
}
173
181
174
182
/**
175
- * Gets a variable with `name` which is declared in a scope above this one, and hidden by a variable in this or a
176
- * nested scope.
183
+ * Holds if `hiddenVariable` and `hidingVariable` are a candidate hiding pair at this scope.
177
184
*/
178
- UserVariable getAHidingVariable ( string name ) {
179
- isNameDeclaredAboveHiddenByThisOrNested ( name ) and
185
+ private predicate hidesCandidate (
186
+ UserVariable hiddenVariable , UserVariable hidingVariable , string name
187
+ ) {
180
188
(
181
189
// Declared in this scope
182
- getAVariable ( ) .getName ( ) = name and
183
- result = getAVariable ( ) and
184
- result .getName ( ) = name
190
+ hidingVariable = getVariable ( name ) and
191
+ hiddenVariable = getAVariableHiddenByThisOrNestedScope ( name )
185
192
or
186
193
// Declared in a child scope
187
194
exists ( Scope child |
188
195
getAChildScope ( ) = child and
189
- child .isNameDeclaredInThisOrNestedScope ( name ) and
190
- result = child .getAHidingVariable ( name )
196
+ child .hidesCandidate ( hiddenVariable , hidingVariable , name )
191
197
)
192
198
)
193
199
}
200
+
201
+ /**
202
+ * Holds if `hiddenVariable` is declared in this scope and hidden by `hidingVariable`.
203
+ */
204
+ predicate hides ( UserVariable hiddenVariable , UserVariable hidingVariable , Scope childScope ) {
205
+ exists ( string name |
206
+ hiddenVariable = getAPotentiallyHiddenVariable ( name ) and
207
+ childScope = getAChildScope ( ) and
208
+ childScope .hidesCandidate ( hiddenVariable , hidingVariable , name )
209
+ )
210
+ }
194
211
}
195
212
196
213
class GeneratedBlockStmt extends BlockStmt {
@@ -247,12 +264,7 @@ class TranslationUnit extends SourceFile {
247
264
248
265
/** Holds if `v2` strictly (`v2` is in an inner scope compared to `v1`) hides `v1`. */
249
266
predicate hides_candidateStrict ( UserVariable v1 , UserVariable v2 ) {
250
- exists ( Scope parentScope , Scope childScope , string name |
251
- v1 = parentScope .getAHiddenVariable ( name ) and
252
- childScope = parentScope .getAChildScope ( ) and
253
- v2 = childScope .getAHidingVariable ( name ) and
254
- not v1 = v2
255
- |
267
+ exists ( Scope parentScope , Scope childScope | parentScope .hides ( v1 , v2 , childScope ) |
256
268
// If v1 is a local variable defined in a `DeclStmt` ensure that it is declared before `v2`,
257
269
// otherwise it would not be hidden
258
270
(
0 commit comments