Skip to content

Commit a0954f1

Browse files
committed
C++: Support using enum declarations.
1 parent 38aac1f commit a0954f1

File tree

2 files changed

+32
-10
lines changed

2 files changed

+32
-10
lines changed

cpp/ql/lib/semmle/code/cpp/Namespace.qll

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ class NamespaceDeclarationEntry extends Locatable, @namespace_decl {
156156
* A C++ `using` directive or `using` declaration.
157157
*/
158158
class UsingEntry extends Locatable, @using {
159-
override Location getLocation() { usings(underlyingElement(this), _, result) }
159+
override Location getLocation() { usings(underlyingElement(this), _, result, _) }
160160
}
161161

162162
/**
@@ -166,15 +166,13 @@ class UsingEntry extends Locatable, @using {
166166
* ```
167167
*/
168168
class UsingDeclarationEntry extends UsingEntry {
169-
UsingDeclarationEntry() {
170-
not exists(Namespace n | usings(underlyingElement(this), unresolveElement(n), _))
171-
}
169+
UsingDeclarationEntry() { usings(underlyingElement(this), _, _, 1) }
172170

173171
/**
174172
* Gets the declaration that is referenced by this using declaration. For
175173
* example, `std::string` in `using std::string`.
176174
*/
177-
Declaration getDeclaration() { usings(underlyingElement(this), unresolveElement(result), _) }
175+
Declaration getDeclaration() { usings(underlyingElement(this), unresolveElement(result), _, _) }
178176

179177
override string toString() { result = "using " + this.getDeclaration().getDescription() }
180178
}
@@ -186,19 +184,36 @@ class UsingDeclarationEntry extends UsingEntry {
186184
* ```
187185
*/
188186
class UsingDirectiveEntry extends UsingEntry {
189-
UsingDirectiveEntry() {
190-
exists(Namespace n | usings(underlyingElement(this), unresolveElement(n), _))
191-
}
187+
UsingDirectiveEntry() { usings(underlyingElement(this), _, _, 2) }
192188

193189
/**
194190
* Gets the namespace that is referenced by this using directive. For
195191
* example, `std` in `using namespace std`.
196192
*/
197-
Namespace getNamespace() { usings(underlyingElement(this), unresolveElement(result), _) }
193+
Namespace getNamespace() { usings(underlyingElement(this), unresolveElement(result), _, _) }
198194

199195
override string toString() { result = "using namespace " + this.getNamespace().getFriendlyName() }
200196
}
201197

198+
/**
199+
* A C++ `using enum` declaration. For example:
200+
* ```
201+
* enum class Foo { a, b };
202+
* using enum Foo;
203+
* ```
204+
*/
205+
class UsingEnumDeclarationEntry extends UsingEntry {
206+
UsingEnumDeclarationEntry() { usings(underlyingElement(this), _, _, 3) }
207+
208+
/**
209+
* Gets the enumeration that is referenced by this using directive. For
210+
* example, `Foo` in `using enum Foo`.
211+
*/
212+
Enum getEnum() { usings(underlyingElement(this), unresolveElement(result), _, _) }
213+
214+
override string toString() { result = "using enum " + this.getEnum().getQualifiedName() }
215+
}
216+
202217
/**
203218
* Holds if `g` is an instance of `GlobalNamespace`. This predicate
204219
* is used suppress a warning in `GlobalNamespace.getADeclaration()`

cpp/ql/lib/semmlecode.cpp.dbscheme

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -485,10 +485,17 @@ namespace_decls(
485485
int bodylocation: @location_default ref
486486
);
487487

488+
case @using.kind of
489+
1 = @using_declaration
490+
| 2 = @using_directive
491+
| 3 = @using_enum_declaration
492+
;
493+
488494
usings(
489495
unique int id: @using,
490496
int element_id: @element ref,
491-
int location: @location_default ref
497+
int location: @location_default ref,
498+
int kind: int ref
492499
);
493500

494501
/** The element which contains the `using` declaration. */

0 commit comments

Comments
 (0)