mirror of
https://github.com/github/codeql.git
synced 2025-12-20 18:56:32 +01:00
205 lines
5.7 KiB
Plaintext
205 lines
5.7 KiB
Plaintext
/**
|
|
* Provides classes representing C/C++ enums and enum constants.
|
|
*/
|
|
|
|
import semmle.code.cpp.Type
|
|
private import semmle.code.cpp.internal.ResolveClass
|
|
|
|
/**
|
|
* A C/C++ enum [N4140 7.2]. For example, the types `MyEnum` and
|
|
* `MyScopedEnum` in:
|
|
* ```
|
|
* enum MyEnum {
|
|
* MyEnumConstant
|
|
* };
|
|
*
|
|
* enum class MyScopedEnum {
|
|
* MyScopedEnumConstant
|
|
* };
|
|
* ```
|
|
* This includes C++ scoped enums, see the `ScopedEnum` QL class.
|
|
*/
|
|
class Enum extends UserType, IntegralOrEnumType {
|
|
/** Gets an enumerator of this enumeration. */
|
|
EnumConstant getAnEnumConstant() { result.getDeclaringEnum() = this }
|
|
|
|
/**
|
|
* Gets the enumerator of this enumeration that was declared at the zero-based position `index`.
|
|
* For example, `zero` is at index 2 in the following declaration:
|
|
* ```
|
|
* enum ReversedOrder {
|
|
* two = 2,
|
|
* one = 1,
|
|
* zero = 0
|
|
* };
|
|
* ```
|
|
*/
|
|
EnumConstant getEnumConstant(int index) {
|
|
enumconstants(unresolveElement(result), underlyingElement(this), index, _, _, _)
|
|
}
|
|
|
|
override string getAPrimaryQlClass() { result = "Enum" }
|
|
|
|
/**
|
|
* Gets a descriptive string for the enum. This method is only intended to
|
|
* be used for debugging purposes. For more information, see the comment
|
|
* for `Type.explain`.
|
|
*/
|
|
override string explain() { result = "enum " + this.getName() }
|
|
|
|
override int getSize() {
|
|
// Workaround for extractor bug CPP-348: No size information for enums.
|
|
// If the extractor didn't provide a size, assume four bytes.
|
|
result = UserType.super.getSize()
|
|
or
|
|
not exists(UserType.super.getSize()) and result = 4
|
|
}
|
|
|
|
/** See `Type.isDeeplyConst` and `Type.isDeeplyConstBelow`. Internal. */
|
|
override predicate isDeeplyConstBelow() { any() } // No subparts
|
|
|
|
/**
|
|
* Holds if this enum has an enum-base [N4140 7.2].
|
|
* For example: `enum E : int`.
|
|
*/
|
|
predicate hasExplicitUnderlyingType() { derivations(_, underlyingElement(this), _, _, _) }
|
|
|
|
/**
|
|
* The type of the enum-base [N4140 7.2], if it is specified.
|
|
* For example: `int` in `enum E : int`.
|
|
*/
|
|
Type getExplicitUnderlyingType() {
|
|
derivations(_, underlyingElement(this), _, unresolveElement(result), _)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* A C/C++ enum that is directly enclosed by a function. For example, the type
|
|
* `MyLocalEnum` in:
|
|
* ```
|
|
* void myFunction() {
|
|
* enum MyLocalEnum {
|
|
* MyLocalEnumConstant
|
|
* };
|
|
* }
|
|
* ```
|
|
*/
|
|
class LocalEnum extends Enum {
|
|
LocalEnum() { this.isLocal() }
|
|
|
|
override string getAPrimaryQlClass() { result = "LocalEnum" }
|
|
}
|
|
|
|
/**
|
|
* A C/C++ enum that is declared within a class/struct. For example, the type
|
|
* `MyNestedEnum` in:
|
|
* ```
|
|
* class MyClass {
|
|
* public:
|
|
* enum MyNestedEnum {
|
|
* MyNestedEnumConstant
|
|
* };
|
|
* };
|
|
* ```
|
|
*/
|
|
class NestedEnum extends Enum {
|
|
NestedEnum() { this.isMember() }
|
|
|
|
override string getAPrimaryQlClass() { result = "NestedEnum" }
|
|
|
|
/** Holds if this member is private. */
|
|
predicate isPrivate() { this.hasSpecifier("private") }
|
|
|
|
/** Holds if this member is protected. */
|
|
predicate isProtected() { this.hasSpecifier("protected") }
|
|
|
|
/** Holds if this member is public. */
|
|
predicate isPublic() { this.hasSpecifier("public") }
|
|
}
|
|
|
|
/**
|
|
* A C++ scoped enum, that is, an enum whose constants must be qualified with
|
|
* the name of the enum. For example, the type `Color` in:
|
|
* ```
|
|
* enum class Color {
|
|
* red,
|
|
* blue
|
|
* }
|
|
* ```
|
|
*/
|
|
class ScopedEnum extends Enum {
|
|
ScopedEnum() { usertypes(underlyingElement(this), _, 13) }
|
|
|
|
override string getAPrimaryQlClass() { result = "ScopedEnum" }
|
|
}
|
|
|
|
/**
|
|
* A C/C++ enumerator [N4140 7.2], also known as an enumeration constant.
|
|
*
|
|
* For example the enumeration constant `green` in:
|
|
* ```
|
|
* enum {
|
|
* red,
|
|
* green,
|
|
* blue
|
|
* }
|
|
* ```
|
|
*/
|
|
class EnumConstant extends Declaration, @enumconstant {
|
|
/**
|
|
* Gets the enumeration of which this enumerator is a member.
|
|
*/
|
|
Enum getDeclaringEnum() {
|
|
enumconstants(underlyingElement(this), unresolveElement(result), _, _, _, _)
|
|
}
|
|
|
|
override string getAPrimaryQlClass() { result = "EnumConstant" }
|
|
|
|
override Class getDeclaringType() { result = this.getDeclaringEnum().getDeclaringType() }
|
|
|
|
/**
|
|
* Gets the name of this enumerator.
|
|
*/
|
|
override string getName() { enumconstants(underlyingElement(this), _, _, _, result, _) }
|
|
|
|
/**
|
|
* Gets the value that this enumerator is initialized to, as a
|
|
* string. This can be a value explicitly given to the enumerator, or an
|
|
* automatically assigned value.
|
|
*/
|
|
string getValue() { result = this.getInitializer().getExpr().getValue() }
|
|
|
|
/** Gets the type of this enumerator. */
|
|
Type getType() { enumconstants(underlyingElement(this), _, _, unresolveElement(result), _, _) }
|
|
|
|
/** Gets the location of a declaration of this enumerator. */
|
|
override Location getADeclarationLocation() { result = this.getDefinitionLocation() }
|
|
|
|
/** Gets the location of the definition of this enumerator. */
|
|
override Location getDefinitionLocation() {
|
|
enumconstants(underlyingElement(this), _, _, _, _, result)
|
|
}
|
|
|
|
/** Gets the location of the definition of this enumerator. */
|
|
override Location getLocation() { result = this.getDefinitionLocation() }
|
|
|
|
/** Gets the initializer of this enumerator, if any. */
|
|
Initializer getInitializer() { result.getDeclaration() = this }
|
|
|
|
/** Gets an access of this enumerator. */
|
|
EnumConstantAccess getAnAccess() { result.getTarget() = this }
|
|
|
|
/** Gets a specifier of this enumerator. */
|
|
override Specifier getASpecifier() {
|
|
varspecifiers(underlyingElement(this), unresolveElement(result))
|
|
}
|
|
|
|
/**
|
|
* An attribute of this enumerator.
|
|
*
|
|
* Note that allowing attributes on enumerators is a language extension
|
|
* which is only supported by Clang.
|
|
*/
|
|
Attribute getAnAttribute() { varattributes(underlyingElement(this), unresolveElement(result)) }
|
|
}
|