@@ -57,10 +57,18 @@ private Element getParentScope(Element e) {
5757
5858/** A variable which is defined by the user, rather than being from a third party or compiler generated. */
5959class 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 ( ) {
6166 exists ( getFile ( ) .getRelativePath ( ) ) and
62- not isCompilerGenerated ( ) and
67+ not this .( Variable ) .isCompilerGenerated ( ) and
68+ not this .( Function ) .isCompilerGenerated ( ) and
6369 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
6472 // compiler inferred parameters have name of p#0
6573 not this .( Parameter ) .getName ( ) = "p#0"
6674 }
@@ -74,11 +82,13 @@ class Scope extends Element {
7482
7583 int getNumberOfVariables ( ) { result = count ( getAVariable ( ) ) }
7684
85+ int getNumberOfDeclarations ( ) { result = count ( getADeclaration ( ) ) }
86+
7787 Scope getAnAncestor ( ) { result = this .getStrictParent + ( ) }
7888
7989 Scope getStrictParent ( ) { result = getParentScope ( this ) }
8090
81- Declaration getADeclaration ( ) { getParentScope ( result ) = this }
91+ UserDeclaration getADeclaration ( ) { getParentScope ( result ) = this }
8292
8393 Expr getAnExpr ( ) { this = getParentScope ( result ) }
8494
@@ -122,31 +132,31 @@ class GeneratedBlockStmt extends BlockStmt {
122132 GeneratedBlockStmt ( ) { this .getLocation ( ) instanceof UnknownLocation }
123133}
124134
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 ) {
127137 exists ( Scope s |
128- result = s .getAVariable ( ) and
138+ result = s .getADeclaration ( ) and
129139 (
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
133143 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
136146 not result = v and
137147 v .getName ( ) <= result .getName ( )
138148 )
139149 )
140150}
141151
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 ) {
144154 exists ( Scope s |
145- result = s .getAVariable ( ) and
155+ result = s .getADeclaration ( ) and
146156 (
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
150160 )
151161 )
152162}
@@ -161,20 +171,20 @@ predicate inSameTranslationUnit(File f1, File f2) {
161171}
162172
163173/**
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`.
165175 */
166176cached
167- UserVariable getPotentialScopeOfVariable ( UserVariable v ) {
168- result = getPotentialScopeOfVariable_candidate ( v ) and
177+ UserDeclaration getPotentialScopeOfDeclarationStrict ( UserDeclaration v ) {
178+ result = getPotentialScopeOfDeclarationStrict_candidate ( v ) and
169179 inSameTranslationUnit ( v .getFile ( ) , result .getFile ( ) )
170180}
171181
172182/**
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`.
174184 */
175185cached
176- UserVariable getPotentialScopeOfVariableStrict ( UserVariable v ) {
177- result = getOuterScopesOfVariable_candidate ( v ) and
186+ UserDeclaration getPotentialScopeOfDeclaration ( UserDeclaration v ) {
187+ result = getPotentialScopeOfDeclaration_candidate ( v ) and
178188 inSameTranslationUnit ( v .getFile ( ) , result .getFile ( ) )
179189}
180190
@@ -204,18 +214,9 @@ class TranslationUnit extends SourceFile {
204214}
205215
206216/** Holds if `v2` may hide `v1`. */
207- private predicate hides_candidate ( UserVariable v1 , UserVariable v2 ) {
217+ private predicate hides_candidateStrict ( UserDeclaration v1 , UserDeclaration v2 ) {
208218 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
219220 v1 .getName ( ) = v2 .getName ( ) and
220221 // Member variables cannot hide other variables nor be hidden because the can be referenced through their qualified name.
221222 not ( v1 .isMember ( ) or v2 .isMember ( ) ) and
@@ -239,6 +240,15 @@ private predicate hides_candidateStrict(UserVariable v1, UserVariable v2) {
239240 )
240241}
241242
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+
242252/**
243253 * Gets the enclosing statement of the given variable, if any.
244254 */
@@ -257,20 +267,22 @@ private Stmt getEnclosingStmt(LocalScopeVariable v) {
257267}
258268
259269/** Holds if `v2` hides `v1`. */
260- predicate hides ( UserVariable v1 , UserVariable v2 ) {
270+ predicate hides ( UserDeclaration v1 , UserDeclaration v2 ) {
261271 hides_candidate ( v1 , v2 ) and
262272 // Confirm that there's no closer candidate variable which `v2` hides
263- not exists ( UserVariable mid |
273+ not exists ( UserDeclaration mid |
264274 hides_candidate ( v1 , mid ) and
265275 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
267279}
268280
269281/** 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 ) {
271283 hides_candidateStrict ( v1 , v2 ) and
272284 // Confirm that there's no closer candidate variable which `v2` hides
273- not exists ( UserVariable mid |
285+ not exists ( UserDeclaration mid |
274286 hides_candidateStrict ( v1 , mid ) and
275287 hides_candidateStrict ( mid , v2 )
276288 )
@@ -287,3 +299,18 @@ predicate hasClassScope(Declaration decl) { exists(decl.getDeclaringType()) }
287299
288300/** Holds if `decl` has block scope. */
289301predicate 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