mirror of
https://github.com/github/codeql.git
synced 2026-04-27 09:45:15 +02:00
Merge branch 'main' into fix-history
This commit is contained in:
@@ -35,8 +35,12 @@ def is_windows():
|
||||
return True
|
||||
return False
|
||||
|
||||
# kotlinc might be kotlinc.bat or kotlinc.cmd on Windows, so we use `which` to find out what it is
|
||||
kotlinc = shutil.which('kotlinc')
|
||||
if kotlinc is None:
|
||||
print("Cannot build the Kotlin extractor: no kotlinc found on your PATH", file = sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
kotlinc = 'kotlinc.bat' if is_windows() else 'kotlinc'
|
||||
javac = 'javac'
|
||||
kotlin_dependency_folder = args.dependencies
|
||||
|
||||
@@ -201,10 +205,6 @@ def compile_standalone(version):
|
||||
'build/temp_src',
|
||||
version)
|
||||
|
||||
if shutil.which(kotlinc) == None:
|
||||
print("Cannot build the Kotlin extractor: no '%s' found on your PATH" % kotlinc, file = sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
if args.many:
|
||||
for version in kotlin_plugin_versions.many_versions:
|
||||
compile_standalone(version)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import platform
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
@@ -26,11 +27,11 @@ class KotlincNotFoundException(Exception):
|
||||
pass
|
||||
|
||||
def get_single_version(fakeVersionOutput = None):
|
||||
# TODO: `shell=True` is a workaround to get CI working on Windows. It breaks the build on Linux.
|
||||
try:
|
||||
versionOutput = subprocess.run(['kotlinc', '-version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, shell=is_windows()).stderr if fakeVersionOutput is None else fakeVersionOutput
|
||||
except FileNotFoundError as e:
|
||||
raise KotlincNotFoundException(e)
|
||||
# kotlinc might be kotlinc.bat or kotlinc.cmd on Windows, so we use `which` to find out what it is
|
||||
kotlinc = shutil.which('kotlinc')
|
||||
if kotlinc is None:
|
||||
raise KotlincNotFoundException()
|
||||
versionOutput = subprocess.run([kotlinc, '-version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True).stderr if fakeVersionOutput is None else fakeVersionOutput
|
||||
m = re.match(r'.* kotlinc-jvm ([0-9]+\.[0-9]+\.[0-9]+) .*', versionOutput)
|
||||
if m is None:
|
||||
raise Exception('Cannot detect version of kotlinc (got ' + str(versionOutput) + ')')
|
||||
|
||||
@@ -21,7 +21,7 @@ class ExternalDeclExtractor(val logger: FileLogger, val invocationTrapFile: Stri
|
||||
|
||||
fun extractLater(d: IrDeclaration, signature: String): Boolean {
|
||||
if (d !is IrClass && !isExternalFileClassMember(d)) {
|
||||
logger.warnElement("External declaration is neither a class, nor a top-level declaration", d)
|
||||
logger.errorElement("External declaration is neither a class, nor a top-level declaration", d)
|
||||
return false
|
||||
}
|
||||
val ret = externalDeclsDone.add(d)
|
||||
@@ -64,7 +64,7 @@ class ExternalDeclExtractor(val logger: FileLogger, val invocationTrapFile: Stri
|
||||
|
||||
val containingClass = getContainingClassOrSelf(irDecl)
|
||||
if (containingClass == null) {
|
||||
logger.warnElement("Unable to get containing class", irDecl)
|
||||
logger.errorElement("Unable to get containing class", irDecl)
|
||||
return
|
||||
}
|
||||
val binaryPath = getIrClassBinaryPath(containingClass)
|
||||
|
||||
@@ -270,7 +270,7 @@ open class KotlinFileExtractor(
|
||||
if (kind == ClassKind.ENUM_CLASS) {
|
||||
tw.writeIsEnumType(classId)
|
||||
} else if (kind != ClassKind.CLASS && kind != ClassKind.OBJECT) {
|
||||
logger.warnElement("Unrecognised class kind $kind", c)
|
||||
logger.errorElement("Unrecognised class kind $kind", c)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -549,7 +549,7 @@ open class KotlinFileExtractor(
|
||||
val constructorId = useFunction<DbConstructor>(enclosingConstructor)
|
||||
val enclosingClass = enclosingConstructor.parentClassOrNull
|
||||
if (enclosingClass == null) {
|
||||
logger.warnElement("Constructor's parent is not a class", enclosingConstructor)
|
||||
logger.errorElement("Constructor's parent is not a class", enclosingConstructor)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -807,13 +807,13 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
} else {
|
||||
if (p.modality != Modality.FINAL || !isExternalDeclaration(p)) {
|
||||
logger.errorElement("IrProperty without a getter", p)
|
||||
logger.warnElement("IrProperty without a getter", p)
|
||||
}
|
||||
}
|
||||
|
||||
if (setter != null) {
|
||||
if (!p.isVar) {
|
||||
logger.errorElement("!isVar property with a setter", p)
|
||||
logger.warnElement("!isVar property with a setter", p)
|
||||
}
|
||||
val setterId = extractFunction(setter, parentId, extractBody = extractFunctionBodies, extractMethodAndParameterTypeAccesses = extractFunctionBodies, typeSubstitution, classTypeArgsIncludingOuterClasses)?.cast<DbMethod>()
|
||||
if (setterId != null) {
|
||||
@@ -821,7 +821,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
} else {
|
||||
if (p.isVar && !isExternalDeclaration(p)) {
|
||||
logger.errorElement("isVar property without a setter", p)
|
||||
logger.warnElement("isVar property without a setter", p)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1657,7 +1657,7 @@ open class KotlinFileExtractor(
|
||||
// as they can't be extracted as external dependencies.
|
||||
isBuiltinCallInternal(c, "less") -> {
|
||||
if(c.origin != IrStatementOrigin.LT) {
|
||||
logger.errorElement("Unexpected origin for LT: ${c.origin}", c)
|
||||
logger.warnElement("Unexpected origin for LT: ${c.origin}", c)
|
||||
}
|
||||
val id = tw.getFreshIdLabel<DbLtexpr>()
|
||||
val type = useType(c.type)
|
||||
@@ -1667,7 +1667,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
isBuiltinCallInternal(c, "lessOrEqual") -> {
|
||||
if(c.origin != IrStatementOrigin.LTEQ) {
|
||||
logger.errorElement("Unexpected origin for LTEQ: ${c.origin}", c)
|
||||
logger.warnElement("Unexpected origin for LTEQ: ${c.origin}", c)
|
||||
}
|
||||
val id = tw.getFreshIdLabel<DbLeexpr>()
|
||||
val type = useType(c.type)
|
||||
@@ -1677,7 +1677,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
isBuiltinCallInternal(c, "greater") -> {
|
||||
if(c.origin != IrStatementOrigin.GT) {
|
||||
logger.errorElement("Unexpected origin for GT: ${c.origin}", c)
|
||||
logger.warnElement("Unexpected origin for GT: ${c.origin}", c)
|
||||
}
|
||||
val id = tw.getFreshIdLabel<DbGtexpr>()
|
||||
val type = useType(c.type)
|
||||
@@ -1687,7 +1687,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
isBuiltinCallInternal(c, "greaterOrEqual") -> {
|
||||
if(c.origin != IrStatementOrigin.GTEQ) {
|
||||
logger.errorElement("Unexpected origin for GTEQ: ${c.origin}", c)
|
||||
logger.warnElement("Unexpected origin for GTEQ: ${c.origin}", c)
|
||||
}
|
||||
val id = tw.getFreshIdLabel<DbGeexpr>()
|
||||
val type = useType(c.type)
|
||||
@@ -1697,7 +1697,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
isBuiltinCallInternal(c, "EQEQ") -> {
|
||||
if(c.origin != IrStatementOrigin.EQEQ) {
|
||||
logger.errorElement("Unexpected origin for EQEQ: ${c.origin}", c)
|
||||
logger.warnElement("Unexpected origin for EQEQ: ${c.origin}", c)
|
||||
}
|
||||
val id = tw.getFreshIdLabel<DbValueeqexpr>()
|
||||
val type = useType(c.type)
|
||||
@@ -1707,7 +1707,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
isBuiltinCallInternal(c, "EQEQEQ") -> {
|
||||
if(c.origin != IrStatementOrigin.EQEQEQ) {
|
||||
logger.errorElement("Unexpected origin for EQEQEQ: ${c.origin}", c)
|
||||
logger.warnElement("Unexpected origin for EQEQEQ: ${c.origin}", c)
|
||||
}
|
||||
val id = tw.getFreshIdLabel<DbEqexpr>()
|
||||
val type = useType(c.type)
|
||||
@@ -1717,7 +1717,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
isBuiltinCallInternal(c, "ieee754equals") -> {
|
||||
if(c.origin != IrStatementOrigin.EQEQ) {
|
||||
logger.errorElement("Unexpected origin for ieee754equals: ${c.origin}", c)
|
||||
logger.warnElement("Unexpected origin for ieee754equals: ${c.origin}", c)
|
||||
}
|
||||
val id = tw.getFreshIdLabel<DbEqexpr>()
|
||||
val type = useType(c.type)
|
||||
@@ -1727,7 +1727,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
isBuiltinCallInternal(c, "CHECK_NOT_NULL") -> {
|
||||
if(c.origin != IrStatementOrigin.EXCLEXCL) {
|
||||
logger.errorElement("Unexpected origin for CHECK_NOT_NULL: ${c.origin}", c)
|
||||
logger.warnElement("Unexpected origin for CHECK_NOT_NULL: ${c.origin}", c)
|
||||
}
|
||||
|
||||
val id = tw.getFreshIdLabel<DbNotnullexpr>()
|
||||
@@ -2394,7 +2394,7 @@ open class KotlinFileExtractor(
|
||||
val stmtParent = parent.stmt(e, callable)
|
||||
val irConstructor = declarationStack.peek() as? IrConstructor
|
||||
if (irConstructor == null) {
|
||||
logger.warnElement("IrInstanceInitializerCall outside constructor", e)
|
||||
logger.errorElement("IrInstanceInitializerCall outside constructor", e)
|
||||
return
|
||||
}
|
||||
extractInstanceInitializerBlock(stmtParent, irConstructor)
|
||||
@@ -3368,7 +3368,7 @@ open class KotlinFileExtractor(
|
||||
) {
|
||||
with("function reference", functionReferenceExpr) {
|
||||
val target = functionReferenceExpr.reflectionTarget ?: run {
|
||||
logger.errorElement("Expected to find reflection target for function reference. Using underlying symbol instead.", functionReferenceExpr)
|
||||
logger.warnElement("Expected to find reflection target for function reference. Using underlying symbol instead.", functionReferenceExpr)
|
||||
functionReferenceExpr.symbol
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
isFinalField
|
||||
| test.kt:3:3:3:18 | x |
|
||||
#select
|
||||
| test.kt:3:3:3:18 | this.x | test.kt:6:10:6:10 | getX(...) |
|
||||
#select
|
||||
@@ -4,9 +4,7 @@ import semmle.code.java.dataflow.DataFlow
|
||||
class Config extends DataFlow::Configuration {
|
||||
Config() { this = "Config" }
|
||||
|
||||
override predicate isSource(DataFlow::Node n) {
|
||||
n.asExpr().(CompileTimeConstantExpr).getStringValue() = "Source"
|
||||
}
|
||||
override predicate isSource(DataFlow::Node n) { n.asExpr().(StringLiteral).getValue() = "Source" }
|
||||
|
||||
override predicate isSink(DataFlow::Node n) {
|
||||
n.asExpr().(Argument).getCall().getCallee().getName() = "sink"
|
||||
|
||||
@@ -27,7 +27,10 @@ py_binary(
|
||||
py_binary(
|
||||
name = "trapgen",
|
||||
srcs = ["trapgen.py"],
|
||||
data = ["//swift/codegen/templates:trap"],
|
||||
data = [
|
||||
"//swift:dbscheme",
|
||||
"//swift/codegen/templates:trap",
|
||||
],
|
||||
visibility = ["//swift:__subpackages__"],
|
||||
deps = [
|
||||
"//swift/codegen/lib",
|
||||
@@ -38,7 +41,11 @@ py_binary(
|
||||
py_binary(
|
||||
name = "cppgen",
|
||||
srcs = ["cppgen.py"],
|
||||
data = ["//swift/codegen/templates:cpp"],
|
||||
data = [
|
||||
":schema",
|
||||
":schema_includes",
|
||||
"//swift/codegen/templates:cpp",
|
||||
],
|
||||
visibility = ["//swift:__subpackages__"],
|
||||
deps = [
|
||||
"//swift/codegen/lib",
|
||||
|
||||
@@ -12,12 +12,12 @@ _directories:
|
||||
expr: Expr$
|
||||
stmt: Stmt$
|
||||
|
||||
Element:
|
||||
is_unknown: predicate
|
||||
|
||||
File:
|
||||
name: string
|
||||
|
||||
IterableDeclContext:
|
||||
members: Decl*
|
||||
|
||||
Locatable:
|
||||
location: Location
|
||||
|
||||
@@ -32,6 +32,9 @@ Type:
|
||||
diagnostics_name: string
|
||||
canonical_type: Type
|
||||
|
||||
IterableDeclContext:
|
||||
members: Decl*
|
||||
|
||||
ExtensionDecl:
|
||||
_extends:
|
||||
- GenericContext
|
||||
@@ -74,6 +77,8 @@ BuiltinType:
|
||||
|
||||
DependentMemberType:
|
||||
_extends: Type
|
||||
baseType: Type
|
||||
associated_type_decl: AssociatedTypeDecl
|
||||
|
||||
DynamicSelfType:
|
||||
_extends: Type
|
||||
@@ -123,14 +128,12 @@ SugarType:
|
||||
|
||||
TupleType:
|
||||
_extends: Type
|
||||
types: Type*
|
||||
names: string*
|
||||
|
||||
TypeVariableType:
|
||||
_extends: Type
|
||||
|
||||
UnknownType:
|
||||
_extends: Type
|
||||
name: string
|
||||
|
||||
UnresolvedType:
|
||||
_extends: Type
|
||||
|
||||
@@ -232,12 +235,14 @@ GenericTypeParamType:
|
||||
|
||||
ParenType:
|
||||
_extends: SugarType
|
||||
type: Type
|
||||
|
||||
SyntaxSugarType:
|
||||
_extends: SugarType
|
||||
|
||||
TypeAliasType:
|
||||
_extends: SugarType
|
||||
decl: TypeAliasDecl
|
||||
|
||||
EnumCaseDecl:
|
||||
_extends: Decl
|
||||
@@ -254,6 +259,7 @@ MissingMemberDecl:
|
||||
|
||||
OperatorDecl:
|
||||
_extends: Decl
|
||||
name: string
|
||||
|
||||
PatternBindingDecl:
|
||||
_extends: Decl
|
||||
@@ -270,15 +276,6 @@ TopLevelCodeDecl:
|
||||
_extends: Decl
|
||||
body: BraceStmt
|
||||
|
||||
UnknownAstNode:
|
||||
_extends:
|
||||
- Decl
|
||||
- Expr
|
||||
- Pattern
|
||||
- Stmt
|
||||
- TypeRepr
|
||||
name: string
|
||||
|
||||
ValueDecl:
|
||||
_extends: Decl
|
||||
interface_type: Type
|
||||
@@ -599,6 +596,7 @@ YieldStmt:
|
||||
|
||||
BoundGenericType:
|
||||
_extends: NominalOrBoundGenericNominalType
|
||||
arg_types: Type*
|
||||
|
||||
NominalType:
|
||||
_extends: NominalOrBoundGenericNominalType
|
||||
@@ -608,6 +606,7 @@ BuiltinIntegerLiteralType:
|
||||
|
||||
BuiltinIntegerType:
|
||||
_extends: AnyBuiltinIntegerType
|
||||
width: int?
|
||||
|
||||
NestedArchetypeType:
|
||||
_extends: ArchetypeType
|
||||
@@ -627,12 +626,16 @@ PrimaryArchetypeType:
|
||||
|
||||
DictionaryType:
|
||||
_extends: SyntaxSugarType
|
||||
key_type: Type
|
||||
value_type: Type
|
||||
|
||||
UnarySyntaxSugarType:
|
||||
_extends: SyntaxSugarType
|
||||
base_type: Type
|
||||
|
||||
InfixOperatorDecl:
|
||||
_extends: OperatorDecl
|
||||
precedence_group: PrecedenceGroupDecl?
|
||||
|
||||
PostfixOperatorDecl:
|
||||
_extends: OperatorDecl
|
||||
@@ -659,6 +662,7 @@ EnumElementDecl:
|
||||
TypeDecl:
|
||||
_extends: ValueDecl
|
||||
name: string
|
||||
base_types: Type*
|
||||
|
||||
AutoClosureExpr:
|
||||
_extends: AbstractClosureExpr
|
||||
@@ -859,9 +863,10 @@ DoStmt:
|
||||
|
||||
ForEachStmt:
|
||||
_extends: LabeledStmt
|
||||
body: BraceStmt
|
||||
pattern: Pattern
|
||||
sequence: Expr
|
||||
where: Expr?
|
||||
body: BraceStmt
|
||||
|
||||
LabeledConditionalStmt:
|
||||
_extends: LabeledStmt
|
||||
@@ -893,7 +898,6 @@ BoundGenericStructType:
|
||||
|
||||
ClassType:
|
||||
_extends: NominalType
|
||||
decl: ClassDecl
|
||||
|
||||
EnumType:
|
||||
_extends: NominalType
|
||||
@@ -903,7 +907,6 @@ ProtocolType:
|
||||
|
||||
StructType:
|
||||
_extends: NominalType
|
||||
decl: StructDecl
|
||||
|
||||
ArraySliceType:
|
||||
_extends: UnarySyntaxSugarType
|
||||
@@ -930,6 +933,9 @@ VarDecl:
|
||||
_extends: AbstractStorageDecl
|
||||
name: string
|
||||
type: Type
|
||||
attached_property_wrapper_type: Type?
|
||||
parent_pattern: Pattern?
|
||||
parent_initializer: Expr?
|
||||
|
||||
AbstractTypeParamDecl:
|
||||
_extends: TypeDecl
|
||||
@@ -1026,3 +1032,87 @@ FloatLiteralExpr:
|
||||
IntegerLiteralExpr:
|
||||
_extends: NumberLiteralExpr
|
||||
string_value: string
|
||||
|
||||
ErrorTypeRepr:
|
||||
_extends: TypeRepr
|
||||
|
||||
AttributedTypeRepr:
|
||||
_extends: TypeRepr
|
||||
|
||||
IdentTypeRepr:
|
||||
_extends: TypeRepr
|
||||
|
||||
ComponentIdentTypeRepr:
|
||||
_extends: IdentTypeRepr
|
||||
|
||||
SimpleIdentTypeRepr:
|
||||
_extends: ComponentIdentTypeRepr
|
||||
|
||||
GenericIdentTypeRepr:
|
||||
_extends: ComponentIdentTypeRepr
|
||||
|
||||
CompoundIdentTypeRepr:
|
||||
_extends: IdentTypeRepr
|
||||
|
||||
FunctionTypeRepr:
|
||||
_extends: TypeRepr
|
||||
|
||||
ArrayTypeRepr:
|
||||
_extends: TypeRepr
|
||||
|
||||
DictionaryTypeRepr:
|
||||
_extends: TypeRepr
|
||||
|
||||
OptionalTypeRepr:
|
||||
_extends: TypeRepr
|
||||
|
||||
ImplicitlyUnwrappedOptionalTypeRepr:
|
||||
_extends: TypeRepr
|
||||
|
||||
TupleTypeRepr:
|
||||
_extends: TypeRepr
|
||||
|
||||
CompositionTypeRepr:
|
||||
_extends: TypeRepr
|
||||
|
||||
MetatypeTypeRepr:
|
||||
_extends: TypeRepr
|
||||
|
||||
ProtocolTypeRepr:
|
||||
_extends: TypeRepr
|
||||
|
||||
OpaqueReturnTypeRepr:
|
||||
_extends: TypeRepr
|
||||
|
||||
NamedOpaqueReturnTypeRepr:
|
||||
_extends: TypeRepr
|
||||
|
||||
ExistentialTypeRepr:
|
||||
_extends: TypeRepr
|
||||
|
||||
PlaceholderTypeRepr:
|
||||
_extends: TypeRepr
|
||||
|
||||
SpecifierTypeRepr:
|
||||
_extends: TypeRepr
|
||||
|
||||
InOutTypeRepr:
|
||||
_extends: SpecifierTypeRepr
|
||||
|
||||
SharedTypeRepr:
|
||||
_extends: SpecifierTypeRepr
|
||||
|
||||
OwnedTypeRepr:
|
||||
_extends: SpecifierTypeRepr
|
||||
|
||||
IsolatedTypeRepr:
|
||||
_extends: SpecifierTypeRepr
|
||||
|
||||
CompileTimeConstTypeRepr:
|
||||
_extends: SpecifierTypeRepr
|
||||
|
||||
FixedTypeRepr:
|
||||
_extends: TypeRepr
|
||||
|
||||
SilBoxTypeRepr:
|
||||
_extends: TypeRepr
|
||||
|
||||
@@ -29,5 +29,14 @@ inline std::ostream &operator<<(std::ostream &out, const {{name}}{{trap_affix}}
|
||||
<< {{#get_streamer}}e.{{field_name}}{{/get_streamer}}{{/fields}} << ")";
|
||||
return out;
|
||||
}
|
||||
{{#id}}
|
||||
|
||||
namespace detail {
|
||||
template<>
|
||||
struct ToBindingTrapFunctor<{{type}}> {
|
||||
using type = {{name}}{{trap_affix}};
|
||||
};
|
||||
}
|
||||
{{/id}}
|
||||
{{/traps}}
|
||||
}
|
||||
|
||||
@@ -3,22 +3,24 @@ load("//swift:rules.bzl", "swift_cc_binary")
|
||||
swift_cc_binary(
|
||||
name = "extractor",
|
||||
srcs = [
|
||||
"SwiftDispatcher.h",
|
||||
"SwiftExtractor.cpp",
|
||||
"SwiftExtractor.h",
|
||||
"SwiftExtractorConfiguration.h",
|
||||
"SwiftDispatcher.h",
|
||||
"SwiftTagTraits.h",
|
||||
"main.cpp",
|
||||
"SwiftVisitor.h",
|
||||
"main.cpp",
|
||||
"visitors/DeclVisitor.h",
|
||||
"visitors/ExprVisitor.h",
|
||||
"visitors/StmtVisitor.h",
|
||||
"visitors/TypeVisitor.h",
|
||||
"visitors/PatternVisitor.h",
|
||||
"visitors/StmtVisitor.h",
|
||||
"visitors/TypeReprVisitor.h",
|
||||
"visitors/TypeVisitor.h",
|
||||
"visitors/VisitorBase.h",
|
||||
],
|
||||
visibility = ["//swift:__pkg__"],
|
||||
deps = [
|
||||
"//swift/tools/prebuilt:swift-llvm-support",
|
||||
"//swift/extractor/trap",
|
||||
"//swift/tools/prebuilt:swift-llvm-support",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -10,42 +10,6 @@
|
||||
|
||||
namespace codeql {
|
||||
|
||||
namespace detail {
|
||||
|
||||
// The following `getKindName`s are used within "TBD" TRAP entries to visually mark an AST node as
|
||||
// not properly emitted yet.
|
||||
// TODO: To be replaced with QL counterpart
|
||||
template <typename Parent, typename Kind>
|
||||
inline std::string getKindName(Kind kind) {
|
||||
return Parent::getKindName(kind).str();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline std::string getKindName<swift::TypeBase, swift::TypeKind>(swift::TypeKind kind) {
|
||||
switch (kind) {
|
||||
#define TYPE(CLASS, PARENT) \
|
||||
case swift::TypeKind::CLASS: \
|
||||
return #CLASS;
|
||||
#include "swift/AST/TypeNodes.def"
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
std::string inline getKindName<swift::TypeRepr, swift::TypeReprKind>(swift::TypeReprKind kind) {
|
||||
switch (kind) {
|
||||
#define TYPEREPR(CLASS, PARENT) \
|
||||
case swift::TypeReprKind::CLASS: \
|
||||
return #CLASS;
|
||||
#include "swift/AST/TypeReprNodes.def"
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// The main responsibilities of the SwiftDispatcher are as follows:
|
||||
// * redirect specific AST node emission to a corresponding visitor (statements, expressions, etc.)
|
||||
// * storing TRAP labels for emitted AST nodes (in the TrapLabelStore) to avoid re-emission
|
||||
@@ -57,28 +21,22 @@ class SwiftDispatcher {
|
||||
SwiftDispatcher(const swift::SourceManager& sourceManager, TrapArena& arena, TrapOutput& trap)
|
||||
: sourceManager{sourceManager}, arena{arena}, trap{trap} {}
|
||||
|
||||
// This is a helper method to emit TRAP entries for AST nodes that we don't fully support yet.
|
||||
template <typename Parent, typename Child>
|
||||
void TBD(Child* entity, const std::string& suffix) {
|
||||
using namespace std::string_literals;
|
||||
auto label = assignNewLabel(entity);
|
||||
auto kind = detail::getKindName<Parent>(static_cast<const Parent*>(entity)->getKind());
|
||||
auto name = "TBD ("s + kind + suffix + ")";
|
||||
if constexpr (std::is_same_v<Parent, swift::TypeBase>) {
|
||||
trap.emit(UnknownTypesTrap{label, name});
|
||||
} else {
|
||||
trap.emit(UnknownAstNodesTrap{label, name});
|
||||
}
|
||||
template <typename Entry>
|
||||
void emit(const Entry& entry) {
|
||||
trap.emit(entry);
|
||||
}
|
||||
|
||||
private:
|
||||
// types to be supported by assignNewLabel/fetchLabel need to be listed here
|
||||
using Store = TrapLabelStore<swift::Decl,
|
||||
swift::Stmt,
|
||||
swift::Expr,
|
||||
swift::Pattern,
|
||||
swift::TypeRepr,
|
||||
swift::TypeBase>;
|
||||
// This is a helper method to emit TRAP entries for AST nodes that we don't fully support yet.
|
||||
template <typename E>
|
||||
void emitUnknown(E* entity) {
|
||||
auto label = assignNewLabel(entity);
|
||||
using Trap = BindingTrapOf<E>;
|
||||
static_assert(sizeof(Trap) == sizeof(label),
|
||||
"Binding traps of unknown entities must only have the `id` field (the class "
|
||||
"should be empty in schema.yml)");
|
||||
emit(Trap{label});
|
||||
emit(ElementIsUnknownTrap{label});
|
||||
}
|
||||
|
||||
// This method gives a TRAP label for already emitted AST node.
|
||||
// If the AST node was not emitted yet, then the emission is dispatched to a corresponding
|
||||
@@ -88,7 +46,7 @@ class SwiftDispatcher {
|
||||
// this is required so we avoid any recursive loop: a `fetchLabel` during the visit of `e` might
|
||||
// end up calling `fetchLabel` on `e` itself, so we want the visit of `e` to call `fetchLabel`
|
||||
// only after having called `assignNewLabel` on `e`.
|
||||
assert(holds_alternative<std::monostate>(waitingForNewLabel) &&
|
||||
assert(std::holds_alternative<std::monostate>(waitingForNewLabel) &&
|
||||
"fetchLabel called before assignNewLabel");
|
||||
if (auto l = store.get(e)) {
|
||||
return *l;
|
||||
@@ -105,22 +63,38 @@ class SwiftDispatcher {
|
||||
return {};
|
||||
}
|
||||
|
||||
// convenience `fetchLabel` overload for `swift::Type` (which is just a wrapper for
|
||||
// `swift::TypeBase*`)
|
||||
TrapLabel<TypeTag> fetchLabel(swift::Type t) { return fetchLabel(t.getPointer()); }
|
||||
|
||||
TrapLabel<AstNodeTag> fetchLabel(swift::ASTNode node) {
|
||||
return fetchLabelFromUnion<AstNodeTag>(node);
|
||||
}
|
||||
|
||||
// Due to the lazy emission approach, we must assign a label to a corresponding AST node before
|
||||
// it actually gets emitted to handle recursive cases such as recursive calls, or recursive type
|
||||
// declarations
|
||||
template <typename E>
|
||||
TrapLabelOf<E> assignNewLabel(E* e) {
|
||||
assert(waitingForNewLabel == Store::Handle{e} && "assignNewLabel called on wrong entity");
|
||||
auto label = getLabel<TrapTagOf<E>>();
|
||||
trap.assignStar(label);
|
||||
auto label = createLabel<TrapTagOf<E>>();
|
||||
store.insert(e, label);
|
||||
waitingForNewLabel = std::monostate{};
|
||||
return label;
|
||||
}
|
||||
|
||||
template <typename Tag>
|
||||
TrapLabel<Tag> getLabel() {
|
||||
return arena.allocateLabel<Tag>();
|
||||
TrapLabel<Tag> createLabel() {
|
||||
auto ret = arena.allocateLabel<Tag>();
|
||||
trap.assignStar(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename Tag, typename... Args>
|
||||
TrapLabel<Tag> createLabel(Args&&... args) {
|
||||
auto ret = arena.allocateLabel<Tag>();
|
||||
trap.assignKey(ret, std::forward<Args>(args)...);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename Locatable>
|
||||
@@ -128,29 +102,70 @@ class SwiftDispatcher {
|
||||
attachLocation(&locatable, locatableLabel);
|
||||
}
|
||||
|
||||
// Emits a Location TRAP entry and attaches it to an AST node
|
||||
// Emits a Location TRAP entry and attaches it to a `Locatable` trap label
|
||||
template <typename Locatable>
|
||||
void attachLocation(Locatable* locatable, TrapLabel<LocatableTag> locatableLabel) {
|
||||
auto start = locatable->getStartLoc();
|
||||
auto end = locatable->getEndLoc();
|
||||
attachLocation(locatable->getStartLoc(), locatable->getEndLoc(), locatableLabel);
|
||||
}
|
||||
|
||||
// Emits a Location TRAP entry for a list of swift entities and attaches it to a `Locatable` trap
|
||||
// label
|
||||
template <typename Locatable>
|
||||
void attachLocation(llvm::MutableArrayRef<Locatable>* locatables,
|
||||
TrapLabel<LocatableTag> locatableLabel) {
|
||||
if (locatables->empty()) {
|
||||
return;
|
||||
}
|
||||
attachLocation(locatables->front().getStartLoc(), locatables->back().getEndLoc(),
|
||||
locatableLabel);
|
||||
}
|
||||
|
||||
private:
|
||||
// types to be supported by assignNewLabel/fetchLabel need to be listed here
|
||||
using Store = TrapLabelStore<swift::Decl,
|
||||
swift::Stmt,
|
||||
swift::StmtCondition,
|
||||
swift::CaseLabelItem,
|
||||
swift::Expr,
|
||||
swift::Pattern,
|
||||
swift::TypeRepr,
|
||||
swift::TypeBase>;
|
||||
|
||||
void attachLocation(swift::SourceLoc start,
|
||||
swift::SourceLoc end,
|
||||
TrapLabel<LocatableTag> locatableLabel) {
|
||||
if (!start.isValid() || !end.isValid()) {
|
||||
// invalid locations seem to come from entities synthesized by the compiler
|
||||
return;
|
||||
}
|
||||
std::string filepath = getFilepath(start);
|
||||
auto fileLabel = arena.allocateLabel<FileTag>();
|
||||
trap.assignKey(fileLabel, filepath);
|
||||
auto fileLabel = createLabel<FileTag>(filepath);
|
||||
// TODO: do not emit duplicate trap entries for Files
|
||||
trap.emit(FilesTrap{fileLabel, filepath});
|
||||
auto [startLine, startColumn] = sourceManager.getLineAndColumnInBuffer(start);
|
||||
auto [endLine, endColumn] = sourceManager.getLineAndColumnInBuffer(end);
|
||||
auto locLabel = arena.allocateLabel<LocationTag>();
|
||||
trap.assignKey(locLabel, '{', fileLabel, "}:", startLine, ':', startColumn, ':', endLine, ':',
|
||||
endColumn);
|
||||
auto locLabel = createLabel<LocationTag>('{', fileLabel, "}:", startLine, ':', startColumn, ':',
|
||||
endLine, ':', endColumn);
|
||||
trap.emit(LocationsTrap{locLabel, fileLabel, startLine, startColumn, endLine, endColumn});
|
||||
trap.emit(LocatablesTrap{locatableLabel, locLabel});
|
||||
}
|
||||
|
||||
template <typename Tag, typename... Ts>
|
||||
TrapLabel<Tag> fetchLabelFromUnion(const llvm::PointerUnion<Ts...> u) {
|
||||
TrapLabel<Tag> ret{};
|
||||
assert((... || fetchLabelFromUnionCase<Tag, Ts>(u, ret)) && "llvm::PointerUnion not set");
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename Tag, typename T, typename... Ts>
|
||||
bool fetchLabelFromUnionCase(const llvm::PointerUnion<Ts...> u, TrapLabel<Tag>& output) {
|
||||
if (auto e = u.template dyn_cast<T>()) {
|
||||
output = fetchLabel(e);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string getFilepath(swift::SourceLoc loc) {
|
||||
// TODO: this needs more testing
|
||||
// TODO: check canonicaliztion of names on a case insensitive filesystems
|
||||
@@ -168,6 +183,8 @@ class SwiftDispatcher {
|
||||
// which are to be introduced in follow-up PRs
|
||||
virtual void visit(swift::Decl* decl) = 0;
|
||||
virtual void visit(swift::Stmt* stmt) = 0;
|
||||
virtual void visit(swift::StmtCondition* cond) = 0;
|
||||
virtual void visit(swift::CaseLabelItem* item) = 0;
|
||||
virtual void visit(swift::Expr* expr) = 0;
|
||||
virtual void visit(swift::Pattern* pattern) = 0;
|
||||
virtual void visit(swift::TypeRepr* type) = 0;
|
||||
|
||||
@@ -14,6 +14,7 @@ using SILBlockStorageTypeTag = SilBlockStorageTypeTag;
|
||||
using SILBoxTypeTag = SilBoxTypeTag;
|
||||
using SILFunctionTypeTag = SilFunctionTypeTag;
|
||||
using SILTokenTypeTag = SilTokenTypeTag;
|
||||
using SILBoxTypeReprTag = SilBoxTypeReprTag;
|
||||
|
||||
#define MAP_TYPE_TO_TAG(TYPE, TAG) \
|
||||
template <> \
|
||||
@@ -34,6 +35,8 @@ using SILTokenTypeTag = SilTokenTypeTag;
|
||||
static_assert(std::is_base_of_v<TYPE##Tag, TAG>, "override is not a subtag");
|
||||
|
||||
MAP_TAG(Stmt);
|
||||
MAP_TAG(StmtCondition);
|
||||
MAP_TAG(CaseLabelItem);
|
||||
#define ABSTRACT_STMT(CLASS, PARENT) MAP_SUBTAG(CLASS##Stmt, PARENT)
|
||||
#define STMT(CLASS, PARENT) ABSTRACT_STMT(CLASS, PARENT)
|
||||
#include "swift/AST/StmtNodes.def"
|
||||
@@ -54,6 +57,10 @@ MAP_TAG(Pattern);
|
||||
#include "swift/AST/PatternNodes.def"
|
||||
|
||||
MAP_TAG(TypeRepr);
|
||||
#define ABSTRACT_TYPEREPR(CLASS, PARENT) MAP_SUBTAG(CLASS##TypeRepr, PARENT)
|
||||
#define TYPEREPR(CLASS, PARENT) ABSTRACT_TYPEREPR(CLASS, PARENT)
|
||||
#include "swift/AST/TypeReprNodes.def"
|
||||
|
||||
MAP_TYPE_TO_TAG(TypeBase, TypeTag);
|
||||
#define ABSTRACT_TYPE(CLASS, PARENT) MAP_SUBTAG(CLASS##Type, PARENT)
|
||||
#define TYPE(CLASS, PARENT) ABSTRACT_TYPE(CLASS, PARENT)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "swift/extractor/visitors/ExprVisitor.h"
|
||||
#include "swift/extractor/visitors/StmtVisitor.h"
|
||||
#include "swift/extractor/visitors/TypeVisitor.h"
|
||||
#include "swift/extractor/visitors/TypeReprVisitor.h"
|
||||
#include "swift/extractor/visitors/PatternVisitor.h"
|
||||
|
||||
namespace codeql {
|
||||
@@ -21,14 +22,17 @@ class SwiftVisitor : private SwiftDispatcher {
|
||||
private:
|
||||
void visit(swift::Decl* decl) override { declVisitor.visit(decl); }
|
||||
void visit(swift::Stmt* stmt) override { stmtVisitor.visit(stmt); }
|
||||
void visit(swift::StmtCondition* cond) override { stmtVisitor.visitStmtCondition(cond); }
|
||||
void visit(swift::CaseLabelItem* item) override { stmtVisitor.visitCaseLabelItem(item); }
|
||||
void visit(swift::Expr* expr) override { exprVisitor.visit(expr); }
|
||||
void visit(swift::Pattern* pattern) override { patternVisitor.visit(pattern); }
|
||||
void visit(swift::TypeRepr* type) override { TBD<swift::TypeRepr>(type, "TypeRepr"); }
|
||||
void visit(swift::TypeRepr* type) override { typeReprVisitor.visit(type); }
|
||||
void visit(swift::TypeBase* type) override { typeVisitor.visit(type); }
|
||||
|
||||
DeclVisitor declVisitor{*this};
|
||||
ExprVisitor exprVisitor{*this};
|
||||
StmtVisitor stmtVisitor{*this};
|
||||
TypeReprVisitor typeReprVisitor{*this};
|
||||
TypeVisitor typeVisitor{*this};
|
||||
PatternVisitor patternVisitor{*this};
|
||||
};
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include "swift/extractor/trap/generated/TrapTags.h"
|
||||
|
||||
namespace codeql {
|
||||
|
||||
class UntypedTrapLabel {
|
||||
@@ -15,12 +13,18 @@ class UntypedTrapLabel {
|
||||
template <typename Tag>
|
||||
friend class TrapLabel;
|
||||
|
||||
static constexpr uint64_t undefined = 0xffffffffffffffff;
|
||||
|
||||
protected:
|
||||
UntypedTrapLabel() : id_{0xffffffffffffffff} {}
|
||||
UntypedTrapLabel() : id_{undefined} {}
|
||||
UntypedTrapLabel(uint64_t id) : id_{id} {}
|
||||
|
||||
public:
|
||||
friend std::ostream& operator<<(std::ostream& out, UntypedTrapLabel l) {
|
||||
// TODO: this is a temporary fix to catch us from outputting undefined labels to trap
|
||||
// this should be moved to a validity check, probably aided by code generation and carried out
|
||||
// by `SwiftDispatcher`
|
||||
assert(l.id_ != undefined && "outputting an undefined label!");
|
||||
out << '#' << std::hex << l.id_ << std::dec;
|
||||
return out;
|
||||
}
|
||||
@@ -46,14 +50,7 @@ class TrapLabel : public UntypedTrapLabel {
|
||||
|
||||
template <typename OtherTag>
|
||||
TrapLabel(const TrapLabel<OtherTag>& other) : UntypedTrapLabel(other) {
|
||||
// we temporarily need to bypass the label type system for unknown AST nodes and types
|
||||
if constexpr (std::is_same_v<Tag, UnknownAstNodeTag>) {
|
||||
static_assert(std::is_base_of_v<AstNodeTag, OtherTag>, "wrong label assignment!");
|
||||
} else if constexpr (std::is_same_v<Tag, UnknownTypeTag>) {
|
||||
static_assert(std::is_base_of_v<TypeTag, OtherTag>, "wrong label assignment!");
|
||||
} else {
|
||||
static_assert(std::is_base_of_v<Tag, OtherTag>, "wrong label assignment!");
|
||||
}
|
||||
static_assert(std::is_base_of_v<Tag, OtherTag>, "wrong label assignment!");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -8,11 +8,17 @@
|
||||
namespace codeql {
|
||||
|
||||
namespace detail {
|
||||
// must be instantiated for default mapping from entities to tags
|
||||
template <typename T>
|
||||
struct ToTagFunctor;
|
||||
|
||||
// can be instantiated to override the default mapping for special cases
|
||||
template <typename T>
|
||||
struct ToTagOverride : ToTagFunctor<T> {};
|
||||
|
||||
// must be instantiated to map trap labels to the corresponding generated binding trap entry
|
||||
template <typename Label>
|
||||
struct ToBindingTrapFunctor;
|
||||
} // namespace detail
|
||||
|
||||
template <typename T>
|
||||
@@ -21,4 +27,7 @@ using TrapTagOf = typename detail::ToTagOverride<std::remove_const_t<T>>::type;
|
||||
template <typename T>
|
||||
using TrapLabelOf = TrapLabel<TrapTagOf<T>>;
|
||||
|
||||
template <typename T>
|
||||
using BindingTrapOf = typename detail::ToBindingTrapFunctor<TrapLabelOf<T>>::type;
|
||||
|
||||
} // namespace codeql
|
||||
|
||||
@@ -1,22 +1,256 @@
|
||||
#pragma once
|
||||
|
||||
#include "swift/extractor/SwiftDispatcher.h"
|
||||
#include <swift/AST/ASTVisitor.h>
|
||||
#include <swift/AST/Decl.h>
|
||||
#include <swift/AST/GenericParamList.h>
|
||||
#include <swift/AST/ParameterList.h>
|
||||
|
||||
#include "swift/extractor/visitors/VisitorBase.h"
|
||||
|
||||
namespace codeql {
|
||||
|
||||
class DeclVisitor : public swift::DeclVisitor<DeclVisitor> {
|
||||
// `swift::Decl` visitor
|
||||
// public `visitXXX(swift::XXX* decl)` methods visit concrete declarations
|
||||
// private `emitXXX(swift::XXX* decl, TrapLabel<XXXTag> label)` are used to fill the properties
|
||||
// related to an abstract `XXX` entity, given the label assigned to the concrete entry
|
||||
// In general, `visitXXX/emitXXX` should call `emitYYY` with `YYY` the direct superclass of `XXX`
|
||||
// (if not `Decl` itself)
|
||||
// TODO: maybe make the above chain of calls automatic with a bit of macro metaprogramming?
|
||||
class DeclVisitor : public AstVisitorBase<DeclVisitor> {
|
||||
public:
|
||||
// SwiftDispatcher should outlive the DeclVisitor
|
||||
DeclVisitor(SwiftDispatcher& dispatcher) : dispatcher(dispatcher) {}
|
||||
using AstVisitorBase<DeclVisitor>::AstVisitorBase;
|
||||
|
||||
template <typename E>
|
||||
void visitDecl(E* decl) {
|
||||
dispatcher.TBD<swift::Decl>(decl, "Decl");
|
||||
void visitFuncDecl(swift::FuncDecl* decl) {
|
||||
auto label = dispatcher_.assignNewLabel(decl);
|
||||
dispatcher_.emit(ConcreteFuncDeclsTrap{label});
|
||||
emitAbstractFunctionDecl(decl, label);
|
||||
}
|
||||
|
||||
void visitConstructorDecl(swift::ConstructorDecl* decl) {
|
||||
auto label = dispatcher_.assignNewLabel(decl);
|
||||
dispatcher_.emit(ConstructorDeclsTrap{label});
|
||||
emitConstructorDecl(decl, label);
|
||||
}
|
||||
|
||||
void visitDestructorDecl(swift::DestructorDecl* decl) {
|
||||
auto label = dispatcher_.assignNewLabel(decl);
|
||||
dispatcher_.emit(DestructorDeclsTrap{label});
|
||||
emitDestructorDecl(decl, label);
|
||||
}
|
||||
|
||||
void visitPrefixOperatorDecl(swift::PrefixOperatorDecl* decl) {
|
||||
auto label = dispatcher_.assignNewLabel(decl);
|
||||
dispatcher_.emit(PrefixOperatorDeclsTrap{label});
|
||||
emitOperatorDecl(decl, label);
|
||||
}
|
||||
|
||||
void visitPostfixOperatorDecl(swift::PostfixOperatorDecl* decl) {
|
||||
auto label = dispatcher_.assignNewLabel(decl);
|
||||
dispatcher_.emit(PostfixOperatorDeclsTrap{label});
|
||||
emitOperatorDecl(decl, label);
|
||||
}
|
||||
|
||||
void visitInfixOperatorDecl(swift::InfixOperatorDecl* decl) {
|
||||
auto label = dispatcher_.assignNewLabel(decl);
|
||||
dispatcher_.emit(InfixOperatorDeclsTrap{label});
|
||||
if (auto group = decl->getPrecedenceGroup()) {
|
||||
dispatcher_.emit(InfixOperatorDeclPrecedenceGroupsTrap{label, dispatcher_.fetchLabel(group)});
|
||||
}
|
||||
emitOperatorDecl(decl, label);
|
||||
}
|
||||
|
||||
void visitPrecedenceGroupDecl(swift::PrecedenceGroupDecl* decl) {
|
||||
auto label = dispatcher_.assignNewLabel(decl);
|
||||
dispatcher_.emit(PrecedenceGroupDeclsTrap{label});
|
||||
}
|
||||
|
||||
void visitParamDecl(swift::ParamDecl* decl) {
|
||||
auto label = dispatcher_.assignNewLabel(decl);
|
||||
dispatcher_.emit(ParamDeclsTrap{label});
|
||||
emitVarDecl(decl, label);
|
||||
}
|
||||
|
||||
void visitTopLevelCodeDecl(swift::TopLevelCodeDecl* decl) {
|
||||
auto label = dispatcher_.assignNewLabel(decl);
|
||||
assert(decl->getBody() && "Expect top level code to have body");
|
||||
dispatcher_.emit(TopLevelCodeDeclsTrap{label, dispatcher_.fetchLabel(decl->getBody())});
|
||||
}
|
||||
|
||||
void visitPatternBindingDecl(swift::PatternBindingDecl* decl) {
|
||||
auto label = dispatcher_.assignNewLabel(decl);
|
||||
dispatcher_.emit(PatternBindingDeclsTrap{label});
|
||||
for (unsigned i = 0; i < decl->getNumPatternEntries(); ++i) {
|
||||
auto pattern = decl->getPattern(i);
|
||||
assert(pattern && "Expect pattern binding decl to have all patterns");
|
||||
dispatcher_.emit(PatternBindingDeclPatternsTrap{label, i, dispatcher_.fetchLabel(pattern)});
|
||||
if (auto init = decl->getInit(i)) {
|
||||
dispatcher_.emit(PatternBindingDeclInitsTrap{label, i, dispatcher_.fetchLabel(init)});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void visitVarDecl(swift::VarDecl* decl) {
|
||||
auto label = dispatcher_.assignNewLabel(decl);
|
||||
auto introducer = static_cast<uint8_t>(decl->getIntroducer());
|
||||
dispatcher_.emit(ConcreteVarDeclsTrap{label, introducer});
|
||||
emitVarDecl(decl, label);
|
||||
}
|
||||
|
||||
void visitStructDecl(swift::StructDecl* decl) {
|
||||
auto label = dispatcher_.assignNewLabel(decl);
|
||||
dispatcher_.emit(StructDeclsTrap{label});
|
||||
emitNominalTypeDecl(decl, label);
|
||||
}
|
||||
|
||||
void visitClassDecl(swift::ClassDecl* decl) {
|
||||
auto label = dispatcher_.assignNewLabel(decl);
|
||||
dispatcher_.emit(ClassDeclsTrap{label});
|
||||
emitNominalTypeDecl(decl, label);
|
||||
}
|
||||
|
||||
void visitEnumDecl(swift::EnumDecl* decl) {
|
||||
auto label = dispatcher_.assignNewLabel(decl);
|
||||
dispatcher_.emit(EnumDeclsTrap{label});
|
||||
emitNominalTypeDecl(decl, label);
|
||||
}
|
||||
|
||||
void visitProtocolDecl(swift::ProtocolDecl* decl) {
|
||||
auto label = dispatcher_.assignNewLabel(decl);
|
||||
dispatcher_.emit(ProtocolDeclsTrap{label});
|
||||
emitNominalTypeDecl(decl, label);
|
||||
}
|
||||
|
||||
void visitEnumCaseDecl(swift::EnumCaseDecl* decl) {
|
||||
auto label = dispatcher_.assignNewLabel(decl);
|
||||
dispatcher_.emit(EnumCaseDeclsTrap{label});
|
||||
auto i = 0u;
|
||||
for (auto e : decl->getElements()) {
|
||||
dispatcher_.emit(EnumCaseDeclElementsTrap{label, i++, dispatcher_.fetchLabel(e)});
|
||||
}
|
||||
}
|
||||
|
||||
void visitEnumElementDecl(swift::EnumElementDecl* decl) {
|
||||
auto label = dispatcher_.assignNewLabel(decl);
|
||||
dispatcher_.emit(EnumElementDeclsTrap{label, decl->getNameStr().str()});
|
||||
if (decl->hasParameterList()) {
|
||||
auto i = 0u;
|
||||
for (auto p : *decl->getParameterList()) {
|
||||
dispatcher_.emit(EnumElementDeclParamsTrap{label, i++, dispatcher_.fetchLabel(p)});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void visitGenericTypeParamDecl(swift::GenericTypeParamDecl* decl) {
|
||||
auto label = dispatcher_.assignNewLabel(decl);
|
||||
dispatcher_.emit(GenericTypeParamDeclsTrap{label});
|
||||
emitTypeDecl(decl, label);
|
||||
}
|
||||
|
||||
void visitAssociatedTypeDecl(swift::AssociatedTypeDecl* decl) {
|
||||
auto label = dispatcher_.assignNewLabel(decl);
|
||||
dispatcher_.emit(AssociatedTypeDeclsTrap{label});
|
||||
emitTypeDecl(decl, label);
|
||||
}
|
||||
|
||||
void visitTypeAliasDecl(swift::TypeAliasDecl* decl) {
|
||||
auto label = dispatcher_.assignNewLabel(decl);
|
||||
dispatcher_.emit(TypeAliasDeclsTrap{label});
|
||||
emitTypeDecl(decl, label);
|
||||
}
|
||||
|
||||
private:
|
||||
SwiftDispatcher& dispatcher;
|
||||
void emitConstructorDecl(swift::ConstructorDecl* decl, TrapLabel<ConstructorDeclTag> label) {
|
||||
emitAbstractFunctionDecl(decl, label);
|
||||
}
|
||||
|
||||
void emitDestructorDecl(swift::DestructorDecl* decl, TrapLabel<DestructorDeclTag> label) {
|
||||
emitAbstractFunctionDecl(decl, label);
|
||||
}
|
||||
|
||||
void emitAbstractFunctionDecl(swift::AbstractFunctionDecl* decl,
|
||||
TrapLabel<AbstractFunctionDeclTag> label) {
|
||||
assert(decl->hasName() && "Expect functions to have name");
|
||||
assert(decl->hasParameterList() && "Expect functions to have a parameter list");
|
||||
auto name = decl->getName().isSpecial() ? "(unnamed function decl)" : decl->getNameStr().str();
|
||||
dispatcher_.emit(AbstractFunctionDeclsTrap{label, name});
|
||||
if (auto body = decl->getBody()) {
|
||||
dispatcher_.emit(AbstractFunctionDeclBodiesTrap{label, dispatcher_.fetchLabel(body)});
|
||||
}
|
||||
auto params = decl->getParameters();
|
||||
for (auto i = 0u; i < params->size(); ++i) {
|
||||
dispatcher_.emit(
|
||||
AbstractFunctionDeclParamsTrap{label, i, dispatcher_.fetchLabel(params->get(i))});
|
||||
}
|
||||
emitValueDecl(decl, label);
|
||||
emitGenericContext(decl, label);
|
||||
}
|
||||
|
||||
void emitOperatorDecl(swift::OperatorDecl* decl, TrapLabel<OperatorDeclTag> label) {
|
||||
dispatcher_.emit(OperatorDeclsTrap{label, decl->getName().str().str()});
|
||||
}
|
||||
|
||||
void emitTypeDecl(swift::TypeDecl* decl, TrapLabel<TypeDeclTag> label) {
|
||||
dispatcher_.emit(TypeDeclsTrap{label, decl->getNameStr().str()});
|
||||
auto i = 0u;
|
||||
for (auto& typeLoc : decl->getInherited()) {
|
||||
auto type = typeLoc.getType();
|
||||
if (type.isNull()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
dispatcher_.emit(TypeDeclBaseTypesTrap{label, i++, dispatcher_.fetchLabel(type)});
|
||||
}
|
||||
emitValueDecl(decl, label);
|
||||
}
|
||||
|
||||
void emitIterableDeclContext(swift::IterableDeclContext* decl,
|
||||
TrapLabel<IterableDeclContextTag> label) {
|
||||
auto i = 0u;
|
||||
for (auto& member : decl->getAllMembers()) {
|
||||
dispatcher_.emit(IterableDeclContextMembersTrap{label, i++, dispatcher_.fetchLabel(member)});
|
||||
}
|
||||
}
|
||||
|
||||
void emitVarDecl(swift::VarDecl* decl, TrapLabel<VarDeclTag> label) {
|
||||
auto typeLabel = dispatcher_.fetchLabel(decl->getType());
|
||||
dispatcher_.emit(VarDeclsTrap{label, decl->getNameStr().str(), typeLabel});
|
||||
if (auto pattern = decl->getParentPattern()) {
|
||||
dispatcher_.emit(VarDeclParentPatternsTrap{label, dispatcher_.fetchLabel(pattern)});
|
||||
}
|
||||
if (auto init = decl->getParentInitializer()) {
|
||||
dispatcher_.emit(VarDeclParentInitializersTrap{label, dispatcher_.fetchLabel(init)});
|
||||
}
|
||||
if (decl->hasAttachedPropertyWrapper()) {
|
||||
if (auto propertyType = decl->getPropertyWrapperBackingPropertyType();
|
||||
!propertyType.isNull()) {
|
||||
dispatcher_.emit(
|
||||
VarDeclAttachedPropertyWrapperTypesTrap{label, dispatcher_.fetchLabel(propertyType)});
|
||||
}
|
||||
}
|
||||
emitValueDecl(decl, label);
|
||||
}
|
||||
|
||||
void emitNominalTypeDecl(swift::NominalTypeDecl* decl, TrapLabel<NominalTypeDeclTag> label) {
|
||||
auto typeLabel = dispatcher_.fetchLabel(decl->getDeclaredType());
|
||||
dispatcher_.emit(NominalTypeDeclsTrap{label, typeLabel});
|
||||
emitGenericContext(decl, label);
|
||||
emitIterableDeclContext(decl, label);
|
||||
emitTypeDecl(decl, label);
|
||||
}
|
||||
|
||||
void emitGenericContext(const swift::GenericContext* decl, TrapLabel<GenericContextTag> label) {
|
||||
if (auto params = decl->getGenericParams()) {
|
||||
auto i = 0u;
|
||||
for (auto t : *params) {
|
||||
dispatcher_.emit(
|
||||
GenericContextGenericTypeParamsTrap{label, i++, dispatcher_.fetchLabel(t)});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void emitValueDecl(const swift::ValueDecl* decl, TrapLabel<ValueDeclTag> label) {
|
||||
assert(decl->getInterfaceType() && "Expect ValueDecl to have InterfaceType");
|
||||
dispatcher_.emit(ValueDeclsTrap{label, dispatcher_.fetchLabel(decl->getInterfaceType())});
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace codeql
|
||||
|
||||
@@ -1,22 +1,547 @@
|
||||
#pragma once
|
||||
|
||||
#include "swift/extractor/SwiftDispatcher.h"
|
||||
#include <swift/AST/ASTVisitor.h>
|
||||
#include "swift/extractor/visitors/VisitorBase.h"
|
||||
|
||||
namespace codeql {
|
||||
|
||||
class ExprVisitor : public swift::ExprVisitor<ExprVisitor> {
|
||||
class ExprVisitor : public AstVisitorBase<ExprVisitor> {
|
||||
public:
|
||||
// SwiftDispatcher should outlive the ExprVisitor
|
||||
ExprVisitor(SwiftDispatcher& dispatcher) : dispatcher(dispatcher) {}
|
||||
using AstVisitorBase<ExprVisitor>::AstVisitorBase;
|
||||
|
||||
template <typename E>
|
||||
void visitExpr(E* expr) {
|
||||
dispatcher.TBD<swift::Expr>(expr, "Expr");
|
||||
void visit(swift::Expr* expr) {
|
||||
swift::ExprVisitor<ExprVisitor, void>::visit(expr);
|
||||
auto label = dispatcher_.fetchLabel(expr);
|
||||
if (auto type = expr->getType()) {
|
||||
dispatcher_.emit(ExprTypesTrap{label, dispatcher_.fetchLabel(type)});
|
||||
}
|
||||
}
|
||||
|
||||
void visitIntegerLiteralExpr(swift::IntegerLiteralExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
auto value = (expr->isNegative() ? "-" : "") + expr->getDigitsText().str();
|
||||
dispatcher_.emit(IntegerLiteralExprsTrap{label, value});
|
||||
}
|
||||
|
||||
void visitFloatLiteralExpr(swift::FloatLiteralExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
auto value = (expr->isNegative() ? "-" : "") + expr->getDigitsText().str();
|
||||
dispatcher_.emit(FloatLiteralExprsTrap{label, value});
|
||||
}
|
||||
|
||||
void visitBooleanLiteralExpr(swift::BooleanLiteralExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(BooleanLiteralExprsTrap{label, expr->getValue()});
|
||||
}
|
||||
|
||||
void visitMagicIdentifierLiteralExpr(swift::MagicIdentifierLiteralExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
auto kind = swift::MagicIdentifierLiteralExpr::getKindString(expr->getKind()).str();
|
||||
dispatcher_.emit(MagicIdentifierLiteralExprsTrap{label, kind});
|
||||
}
|
||||
|
||||
void visitStringLiteralExpr(swift::StringLiteralExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(StringLiteralExprsTrap{label, expr->getValue().str()});
|
||||
}
|
||||
|
||||
void visitInterpolatedStringLiteralExpr(swift::InterpolatedStringLiteralExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(InterpolatedStringLiteralExprsTrap{label});
|
||||
if (auto interpolation = expr->getInterpolationExpr()) {
|
||||
auto ref = dispatcher_.fetchLabel(interpolation);
|
||||
dispatcher_.emit(InterpolatedStringLiteralExprInterpolationExprsTrap{label, ref});
|
||||
}
|
||||
if (auto count = expr->getInterpolationCountExpr()) {
|
||||
auto ref = dispatcher_.fetchLabel(count);
|
||||
dispatcher_.emit(InterpolatedStringLiteralExprInterpolationCountExprsTrap{label, ref});
|
||||
}
|
||||
if (auto capacity = expr->getLiteralCapacityExpr()) {
|
||||
auto ref = dispatcher_.fetchLabel(capacity);
|
||||
dispatcher_.emit(InterpolatedStringLiteralExprLiteralCapacityExprsTrap{label, ref});
|
||||
}
|
||||
if (auto appending = expr->getAppendingExpr()) {
|
||||
auto ref = dispatcher_.fetchLabel(appending);
|
||||
dispatcher_.emit(InterpolatedStringLiteralExprAppendingExprsTrap{label, ref});
|
||||
}
|
||||
}
|
||||
|
||||
void visitNilLiteralExpr(swift::NilLiteralExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(NilLiteralExprsTrap{label});
|
||||
}
|
||||
|
||||
void visitCallExpr(swift::CallExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(CallExprsTrap{label});
|
||||
emitApplyExpr(expr, label);
|
||||
}
|
||||
|
||||
void visitPrefixUnaryExpr(swift::PrefixUnaryExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(PrefixUnaryExprsTrap{label});
|
||||
emitApplyExpr(expr, label);
|
||||
}
|
||||
|
||||
void visitDeclRefExpr(swift::DeclRefExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(DeclRefExprsTrap{label, dispatcher_.fetchLabel(expr->getDecl())});
|
||||
auto i = 0u;
|
||||
for (auto t : expr->getDeclRef().getSubstitutions().getReplacementTypes()) {
|
||||
dispatcher_.emit(DeclRefExprReplacementTypesTrap{label, i++, dispatcher_.fetchLabel(t)});
|
||||
}
|
||||
}
|
||||
|
||||
void visitAssignExpr(swift::AssignExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
assert(expr->getDest() && "AssignExpr has Dest");
|
||||
assert(expr->getSrc() && "AssignExpr has Src");
|
||||
auto dest = dispatcher_.fetchLabel(expr->getDest());
|
||||
auto src = dispatcher_.fetchLabel(expr->getSrc());
|
||||
dispatcher_.emit(AssignExprsTrap{label, dest, src});
|
||||
}
|
||||
|
||||
void visitBindOptionalExpr(swift::BindOptionalExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
assert(expr->getSubExpr() && "BindOptionalExpr has SubExpr");
|
||||
auto subExpr = dispatcher_.fetchLabel(expr->getSubExpr());
|
||||
dispatcher_.emit(BindOptionalExprsTrap{label, subExpr});
|
||||
}
|
||||
|
||||
void visitCaptureListExpr(swift::CaptureListExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
assert(expr->getClosureBody() && "CaptureListExpr has ClosureBody");
|
||||
auto closureBody = dispatcher_.fetchLabel(expr->getClosureBody());
|
||||
dispatcher_.emit(CaptureListExprsTrap{label, closureBody});
|
||||
unsigned index = 0;
|
||||
for (auto& entry : expr->getCaptureList()) {
|
||||
auto captureLabel = dispatcher_.fetchLabel(entry.PBD);
|
||||
dispatcher_.emit(CaptureListExprBindingDeclsTrap{label, index++, captureLabel});
|
||||
}
|
||||
}
|
||||
|
||||
void visitBinaryExpr(swift::BinaryExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(BinaryExprsTrap{label});
|
||||
emitApplyExpr(expr, label);
|
||||
}
|
||||
|
||||
void visitTupleExpr(swift::TupleExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(TupleExprsTrap{label});
|
||||
unsigned index = 0;
|
||||
for (auto element : expr->getElements()) {
|
||||
auto elementLabel = dispatcher_.fetchLabel(element);
|
||||
dispatcher_.emit(TupleExprElementsTrap{label, index++, elementLabel});
|
||||
}
|
||||
}
|
||||
|
||||
void visitDefaultArgumentExpr(swift::DefaultArgumentExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
assert(expr->getParamDecl() && "DefaultArgumentExpr has getParamDecl");
|
||||
/// TODO: suddenly, getParamDecl is const, monkey-patching it here
|
||||
auto paramLabel = dispatcher_.fetchLabel((swift::ParamDecl*)expr->getParamDecl());
|
||||
dispatcher_.emit(
|
||||
DefaultArgumentExprsTrap{label, paramLabel, static_cast<int>(expr->getParamIndex())});
|
||||
if (expr->isCallerSide()) {
|
||||
auto callSiteDefaultLabel = dispatcher_.fetchLabel(expr->getCallerSideDefaultExpr());
|
||||
dispatcher_.emit(DefaultArgumentExprCallerSideDefaultsTrap{label, callSiteDefaultLabel});
|
||||
}
|
||||
}
|
||||
|
||||
void visitDotSyntaxBaseIgnoredExpr(swift::DotSyntaxBaseIgnoredExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
assert(expr->getLHS() && "DotSyntaxBaseIgnoredExpr has LHS");
|
||||
assert(expr->getRHS() && "DotSyntaxBaseIgnoredExpr has RHS");
|
||||
auto lhs = dispatcher_.fetchLabel(expr->getLHS());
|
||||
auto rhs = dispatcher_.fetchLabel(expr->getRHS());
|
||||
dispatcher_.emit(DotSyntaxBaseIgnoredExprsTrap{label, lhs, rhs});
|
||||
}
|
||||
|
||||
void visitDynamicTypeExpr(swift::DynamicTypeExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
assert(expr->getBase() && "DynamicTypeExpr has Base");
|
||||
auto base = dispatcher_.fetchLabel(expr->getBase());
|
||||
dispatcher_.emit(DynamicTypeExprsTrap{label, base});
|
||||
}
|
||||
|
||||
void visitEnumIsCaseExpr(swift::EnumIsCaseExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
assert(expr->getSubExpr() && "EnumIsCaseExpr has SubExpr");
|
||||
assert(expr->getCaseTypeRepr() && "EnumIsCaseExpr has CaseTypeRepr");
|
||||
assert(expr->getEnumElement() && "EnumIsCaseExpr has EnumElement");
|
||||
auto subExpr = dispatcher_.fetchLabel(expr->getSubExpr());
|
||||
auto typeRepr = dispatcher_.fetchLabel(expr->getCaseTypeRepr());
|
||||
auto enumElement = dispatcher_.fetchLabel(expr->getEnumElement());
|
||||
dispatcher_.emit(EnumIsCaseExprsTrap{label, subExpr, typeRepr, enumElement});
|
||||
}
|
||||
|
||||
void visitMakeTemporarilyEscapableExpr(swift::MakeTemporarilyEscapableExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
assert(expr->getOpaqueValue() && "MakeTemporarilyEscapableExpr has OpaqueValue");
|
||||
assert(expr->getNonescapingClosureValue() &&
|
||||
"MakeTemporarilyEscapableExpr has NonescapingClosureValue");
|
||||
assert(expr->getSubExpr() && "MakeTemporarilyEscapableExpr has SubExpr");
|
||||
auto opaqueValue = dispatcher_.fetchLabel(expr->getOpaqueValue());
|
||||
auto nonescapingClosureValue = dispatcher_.fetchLabel(expr->getNonescapingClosureValue());
|
||||
auto subExpr = dispatcher_.fetchLabel(expr->getSubExpr());
|
||||
dispatcher_.emit(
|
||||
MakeTemporarilyEscapableExprsTrap{label, opaqueValue, nonescapingClosureValue, subExpr});
|
||||
}
|
||||
|
||||
void visitObjCSelectorExpr(swift::ObjCSelectorExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
assert(expr->getSubExpr() && "ObjCSelectorExpr has SubExpr");
|
||||
assert(expr->getMethod() && "ObjCSelectorExpr has Method");
|
||||
auto subExpr = dispatcher_.fetchLabel(expr->getSubExpr());
|
||||
auto method = dispatcher_.fetchLabel(expr->getMethod());
|
||||
dispatcher_.emit(ObjCSelectorExprsTrap{label, subExpr, method});
|
||||
}
|
||||
|
||||
void visitOneWayExpr(swift::OneWayExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
assert(expr->getSubExpr() && "OneWayExpr has SubExpr");
|
||||
auto subExpr = dispatcher_.fetchLabel(expr->getSubExpr());
|
||||
dispatcher_.emit(OneWayExprsTrap{label, subExpr});
|
||||
}
|
||||
|
||||
void visitOpenExistentialExpr(swift::OpenExistentialExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
assert(expr->getSubExpr() && "OpenExistentialExpr has SubExpr");
|
||||
assert(expr->getExistentialValue() && "OpenExistentialExpr has ExistentialValue");
|
||||
assert(expr->getOpaqueValue() && "OpenExistentialExpr has OpaqueValue");
|
||||
auto subExpr = dispatcher_.fetchLabel(expr->getSubExpr());
|
||||
auto existentialValue = dispatcher_.fetchLabel(expr->getExistentialValue());
|
||||
auto opaqueValue = dispatcher_.fetchLabel(expr->getOpaqueValue());
|
||||
dispatcher_.emit(OpenExistentialExprsTrap{label, subExpr, existentialValue, opaqueValue});
|
||||
}
|
||||
|
||||
void visitOptionalEvaluationExpr(swift::OptionalEvaluationExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
assert(expr->getSubExpr() && "OptionalEvaluationExpr has SubExpr");
|
||||
auto subExpr = dispatcher_.fetchLabel(expr->getSubExpr());
|
||||
dispatcher_.emit(OptionalEvaluationExprsTrap{label, subExpr});
|
||||
}
|
||||
|
||||
void visitRebindSelfInConstructorExpr(swift::RebindSelfInConstructorExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
assert(expr->getSubExpr() && "RebindSelfInConstructorExpr has SubExpr");
|
||||
assert(expr->getSelf() && "RebindSelfInConstructorExpr has Self");
|
||||
auto subExpr = dispatcher_.fetchLabel(expr->getSubExpr());
|
||||
auto self = dispatcher_.fetchLabel(expr->getSelf());
|
||||
dispatcher_.emit(RebindSelfInConstructorExprsTrap{label, subExpr, self});
|
||||
}
|
||||
|
||||
void visitSuperRefExpr(swift::SuperRefExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
assert(expr->getSelf() && "SuperRefExpr has Self");
|
||||
auto self = dispatcher_.fetchLabel(expr->getSelf());
|
||||
dispatcher_.emit(SuperRefExprsTrap{label, self});
|
||||
}
|
||||
|
||||
void visitDotSyntaxCallExpr(swift::DotSyntaxCallExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(DotSyntaxCallExprsTrap{label});
|
||||
emitSelfApplyExpr(expr, label);
|
||||
}
|
||||
|
||||
void visitVarargExpansionExpr(swift::VarargExpansionExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
assert(expr->getSubExpr() && "VarargExpansionExpr has getSubExpr()");
|
||||
|
||||
auto subExprLabel = dispatcher_.fetchLabel(expr->getSubExpr());
|
||||
dispatcher_.emit(VarargExpansionExprsTrap{label, subExprLabel});
|
||||
}
|
||||
|
||||
void visitArrayExpr(swift::ArrayExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(ArrayExprsTrap{label});
|
||||
unsigned index = 0;
|
||||
for (auto element : expr->getElements()) {
|
||||
auto elementLabel = dispatcher_.fetchLabel(element);
|
||||
dispatcher_.emit(ArrayExprElementsTrap{label, index++, elementLabel});
|
||||
}
|
||||
}
|
||||
|
||||
void visitErasureExpr(swift::ErasureExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(ErasureExprsTrap{label});
|
||||
emitImplicitConversionExpr(expr, label);
|
||||
}
|
||||
|
||||
void visitTypeExpr(swift::TypeExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(TypeExprsTrap{label});
|
||||
if (auto repr = expr->getTypeRepr()) {
|
||||
auto typeLabel = dispatcher_.fetchLabel(repr);
|
||||
dispatcher_.emit(TypeExprTypeReprsTrap{label, typeLabel});
|
||||
}
|
||||
}
|
||||
|
||||
void visitParenExpr(swift::ParenExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(ParenExprsTrap{label});
|
||||
emitIdentityExpr(expr, label);
|
||||
}
|
||||
|
||||
void visitLoadExpr(swift::LoadExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(LoadExprsTrap{label});
|
||||
emitImplicitConversionExpr(expr, label);
|
||||
}
|
||||
|
||||
void visitInOutExpr(swift::InOutExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
assert(expr->getSubExpr() && "InOutExpr has getSubExpr()");
|
||||
|
||||
auto subExprLabel = dispatcher_.fetchLabel(expr->getSubExpr());
|
||||
dispatcher_.emit(InOutExprsTrap{label, subExprLabel});
|
||||
}
|
||||
|
||||
void visitOpaqueValueExpr(swift::OpaqueValueExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(OpaqueValueExprsTrap{label});
|
||||
}
|
||||
|
||||
void visitTapExpr(swift::TapExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
assert(expr->getVar() && "TapExpr has getVar()");
|
||||
assert(expr->getBody() && "TapExpr has getBody()");
|
||||
|
||||
auto varLabel = dispatcher_.fetchLabel(expr->getVar());
|
||||
auto bodyLabel = dispatcher_.fetchLabel(expr->getBody());
|
||||
|
||||
dispatcher_.emit(TapExprsTrap{label, varLabel, bodyLabel});
|
||||
if (auto subExpr = expr->getSubExpr()) {
|
||||
dispatcher_.emit(TapExprSubExprsTrap{label, dispatcher_.fetchLabel(subExpr)});
|
||||
}
|
||||
}
|
||||
|
||||
void visitTupleElementExpr(swift::TupleElementExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
assert(expr->getBase() && "TupleElementExpr has getBase()");
|
||||
|
||||
auto base = dispatcher_.fetchLabel(expr->getBase());
|
||||
auto index = expr->getFieldNumber();
|
||||
dispatcher_.emit(TupleElementExprsTrap{label, base, index});
|
||||
}
|
||||
|
||||
void visitTryExpr(swift::TryExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(TryExprsTrap{label});
|
||||
emitAnyTryExpr(expr, label);
|
||||
}
|
||||
|
||||
void visitForceTryExpr(swift::ForceTryExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(ForceTryExprsTrap{label});
|
||||
emitAnyTryExpr(expr, label);
|
||||
}
|
||||
|
||||
void visitOptionalTryExpr(swift::OptionalTryExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(OptionalTryExprsTrap{label});
|
||||
emitAnyTryExpr(expr, label);
|
||||
}
|
||||
|
||||
void visitInjectIntoOptionalExpr(swift::InjectIntoOptionalExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(InjectIntoOptionalExprsTrap{label});
|
||||
emitImplicitConversionExpr(expr, label);
|
||||
}
|
||||
|
||||
void visitConstructorRefCallExpr(swift::ConstructorRefCallExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(ConstructorRefCallExprsTrap{label});
|
||||
emitSelfApplyExpr(expr, label);
|
||||
}
|
||||
|
||||
void visitDiscardAssignmentExpr(swift::DiscardAssignmentExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(DiscardAssignmentExprsTrap{label});
|
||||
}
|
||||
|
||||
void visitClosureExpr(swift::ClosureExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
assert(expr->getBody() && "ClosureExpr has getBody()");
|
||||
auto bodyLabel = dispatcher_.fetchLabel(expr->getBody());
|
||||
dispatcher_.emit(ClosureExprsTrap{label, bodyLabel});
|
||||
}
|
||||
|
||||
void visitAutoClosureExpr(swift::AutoClosureExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
assert(expr->getBody() && "AutoClosureExpr has getBody()");
|
||||
auto bodyLabel = dispatcher_.fetchLabel(expr->getBody());
|
||||
dispatcher_.emit(AutoClosureExprsTrap{label, bodyLabel});
|
||||
}
|
||||
|
||||
void visitCoerceExpr(swift::CoerceExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(CoerceExprsTrap{label});
|
||||
emitExplicitCastExpr(expr, label);
|
||||
}
|
||||
|
||||
void visitConditionalCheckedCastExpr(swift::ConditionalCheckedCastExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(ConditionalCheckedCastExprsTrap{label});
|
||||
emitExplicitCastExpr(expr, label);
|
||||
}
|
||||
|
||||
void visitForcedCheckedCastExpr(swift::ForcedCheckedCastExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(ForcedCheckedCastExprsTrap{label});
|
||||
emitExplicitCastExpr(expr, label);
|
||||
}
|
||||
|
||||
void visitIsExpr(swift::IsExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(IsExprsTrap{label});
|
||||
emitExplicitCastExpr(expr, label);
|
||||
}
|
||||
|
||||
void visitSubscriptExpr(swift::SubscriptExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
assert(expr->getBase() && "SubscriptExpr has getBase()");
|
||||
auto baseLabel = dispatcher_.fetchLabel(expr->getBase());
|
||||
dispatcher_.emit(SubscriptExprsTrap{label, baseLabel});
|
||||
|
||||
auto i = 0u;
|
||||
for (const auto& arg : *expr->getArgs()) {
|
||||
dispatcher_.emit(SubscriptExprArgumentsTrap{label, i++, emitArgument(arg)});
|
||||
}
|
||||
}
|
||||
|
||||
void visitDictionaryExpr(swift::DictionaryExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(DictionaryExprsTrap{label});
|
||||
unsigned index = 0;
|
||||
for (auto element : expr->getElements()) {
|
||||
auto elementLabel = dispatcher_.fetchLabel(element);
|
||||
dispatcher_.emit(DictionaryExprElementsTrap{label, index++, elementLabel});
|
||||
}
|
||||
}
|
||||
|
||||
void visitFunctionConversionExpr(swift::FunctionConversionExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(FunctionConversionExprsTrap{label});
|
||||
emitImplicitConversionExpr(expr, label);
|
||||
}
|
||||
|
||||
void visitInOutToPointerExpr(swift::InOutToPointerExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(InOutToPointerExprsTrap{label});
|
||||
emitImplicitConversionExpr(expr, label);
|
||||
}
|
||||
|
||||
void visitMemberRefExpr(swift::MemberRefExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
assert(expr->getBase() && "MemberRefExpr has getBase()");
|
||||
|
||||
auto baseLabel = dispatcher_.fetchLabel(expr->getBase());
|
||||
dispatcher_.emit(MemberRefExprsTrap{label, baseLabel});
|
||||
}
|
||||
|
||||
void visitDerivedToBaseExpr(swift::DerivedToBaseExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(DerivedToBaseExprsTrap{label});
|
||||
emitImplicitConversionExpr(expr, label);
|
||||
}
|
||||
|
||||
void visitKeyPathExpr(swift::KeyPathExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(KeyPathExprsTrap{label});
|
||||
if (!expr->isObjC()) {
|
||||
if (auto path = expr->getParsedPath()) {
|
||||
auto pathLabel = dispatcher_.fetchLabel(path);
|
||||
dispatcher_.emit(KeyPathExprParsedPathsTrap{label, pathLabel});
|
||||
}
|
||||
if (auto root = expr->getParsedPath()) {
|
||||
auto rootLabel = dispatcher_.fetchLabel(root);
|
||||
dispatcher_.emit(KeyPathExprParsedRootsTrap{label, rootLabel});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void visitLazyInitializerExpr(swift::LazyInitializerExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
assert(expr->getSubExpr() && "LazyInitializerExpr has getSubExpr()");
|
||||
auto subExprLabel = dispatcher_.fetchLabel(expr->getSubExpr());
|
||||
dispatcher_.emit(LazyInitializerExprsTrap{label, subExprLabel});
|
||||
}
|
||||
|
||||
void visitForceValueExpr(swift::ForceValueExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
assert(expr->getSubExpr() && "ForceValueExpr has getSubExpr()");
|
||||
|
||||
auto subExprLabel = dispatcher_.fetchLabel(expr->getSubExpr());
|
||||
dispatcher_.emit(ForceValueExprsTrap{label, subExprLabel});
|
||||
}
|
||||
|
||||
void visitPointerToPointerExpr(swift::PointerToPointerExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(PointerToPointerExprsTrap{label});
|
||||
emitImplicitConversionExpr(expr, label);
|
||||
}
|
||||
|
||||
void visitIfExpr(swift::IfExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
assert(expr->getCondExpr() && "IfExpr has getCond()");
|
||||
assert(expr->getThenExpr() && "IfExpr has getThenExpr()");
|
||||
assert(expr->getElseExpr() && "IfExpr has getElseExpr()");
|
||||
|
||||
auto condLabel = dispatcher_.fetchLabel(expr->getCondExpr());
|
||||
auto thenLabel = dispatcher_.fetchLabel(expr->getThenExpr());
|
||||
auto elseLabel = dispatcher_.fetchLabel(expr->getElseExpr());
|
||||
|
||||
dispatcher_.emit(IfExprsTrap{label, condLabel, thenLabel, elseLabel});
|
||||
}
|
||||
|
||||
private:
|
||||
SwiftDispatcher& dispatcher;
|
||||
TrapLabel<ArgumentTag> emitArgument(const swift::Argument& arg) {
|
||||
auto argLabel = dispatcher_.createLabel<ArgumentTag>();
|
||||
assert(arg.getExpr() && "Argument has getExpr");
|
||||
dispatcher_.emit(
|
||||
ArgumentsTrap{argLabel, arg.getLabel().str().str(), dispatcher_.fetchLabel(arg.getExpr())});
|
||||
return argLabel;
|
||||
}
|
||||
|
||||
void emitImplicitConversionExpr(swift::ImplicitConversionExpr* expr,
|
||||
TrapLabel<ImplicitConversionExprTag> label) {
|
||||
assert(expr->getSubExpr() && "ImplicitConversionExpr has getSubExpr()");
|
||||
dispatcher_.emit(
|
||||
ImplicitConversionExprsTrap{label, dispatcher_.fetchLabel(expr->getSubExpr())});
|
||||
}
|
||||
|
||||
void emitExplicitCastExpr(swift::ExplicitCastExpr* expr, TrapLabel<ExplicitCastExprTag> label) {
|
||||
assert(expr->getSubExpr() && "ExplicitCastExpr has getSubExpr()");
|
||||
dispatcher_.emit(ExplicitCastExprsTrap{label, dispatcher_.fetchLabel(expr->getSubExpr())});
|
||||
}
|
||||
|
||||
void emitIdentityExpr(swift::IdentityExpr* expr, TrapLabel<IdentityExprTag> label) {
|
||||
assert(expr->getSubExpr() && "IdentityExpr has getSubExpr()");
|
||||
dispatcher_.emit(IdentityExprsTrap{label, dispatcher_.fetchLabel(expr->getSubExpr())});
|
||||
}
|
||||
|
||||
void emitAnyTryExpr(swift::AnyTryExpr* expr, TrapLabel<AnyTryExprTag> label) {
|
||||
assert(expr->getSubExpr() && "AnyTryExpr has getSubExpr()");
|
||||
dispatcher_.emit(AnyTryExprsTrap{label, dispatcher_.fetchLabel(expr->getSubExpr())});
|
||||
}
|
||||
|
||||
void emitApplyExpr(const swift::ApplyExpr* expr, TrapLabel<ApplyExprTag> label) {
|
||||
assert(expr->getFn() && "CallExpr has Fn");
|
||||
auto fnLabel = dispatcher_.fetchLabel(expr->getFn());
|
||||
dispatcher_.emit(ApplyExprsTrap{label, fnLabel});
|
||||
auto i = 0u;
|
||||
for (const auto& arg : *expr->getArgs()) {
|
||||
dispatcher_.emit(ApplyExprArgumentsTrap{label, i++, emitArgument(arg)});
|
||||
}
|
||||
}
|
||||
|
||||
void emitSelfApplyExpr(const swift::SelfApplyExpr* expr, TrapLabel<SelfApplyExprTag> label) {
|
||||
assert(expr->getBase() && "SelfApplyExpr has getBase()");
|
||||
auto baseLabel = dispatcher_.fetchLabel(expr->getBase());
|
||||
dispatcher_.emit(SelfApplyExprsTrap{label, baseLabel});
|
||||
emitApplyExpr(expr, label);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace codeql
|
||||
|
||||
@@ -1,38 +1,97 @@
|
||||
#pragma once
|
||||
|
||||
#include "swift/extractor/SwiftDispatcher.h"
|
||||
#include <swift/AST/ASTVisitor.h>
|
||||
#include "swift/extractor/visitors/VisitorBase.h"
|
||||
|
||||
namespace codeql {
|
||||
|
||||
namespace detail {
|
||||
// swift code lacks default implementations of visitor for some entities. We can add those here
|
||||
// while we do not have yet all implemented. This is a simplified version of the corresponding Expr
|
||||
// code in swift/AST/ASTVisitor.h
|
||||
template <typename CrtpSubclass>
|
||||
class PatchedPatternVisitor : public swift::PatternVisitor<CrtpSubclass> {
|
||||
class PatternVisitor : public AstVisitorBase<PatternVisitor> {
|
||||
public:
|
||||
#define PATTERN(CLASS, PARENT) \
|
||||
void visit##CLASS##Pattern(swift::CLASS##Pattern* E) { \
|
||||
return static_cast<CrtpSubclass*>(this)->visit##PARENT(E); \
|
||||
}
|
||||
#include "swift/AST/PatternNodes.def"
|
||||
};
|
||||
using AstVisitorBase<PatternVisitor>::AstVisitorBase;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
class PatternVisitor : public detail::PatchedPatternVisitor<PatternVisitor> {
|
||||
public:
|
||||
// SwiftDispatcher should outlive the PatternVisitor
|
||||
PatternVisitor(SwiftDispatcher& dispatcher) : dispatcher(dispatcher) {}
|
||||
|
||||
template <typename E>
|
||||
void visitPattern(E* pattern) {
|
||||
dispatcher.TBD<swift::Pattern>(pattern, "Pattern");
|
||||
void visitNamedPattern(swift::NamedPattern* pattern) {
|
||||
auto label = dispatcher_.assignNewLabel(pattern);
|
||||
// TODO: in some (but not all) cases, this seems to introduce a duplicate entry
|
||||
// for example the vars listed in a case stmt have a different pointer than then ones in
|
||||
// patterns.
|
||||
// assert(pattern->getDecl() && "expect NamedPattern to have Decl");
|
||||
// dispatcher_.emit(NamedPatternsTrap{label, pattern->getNameStr().str(),
|
||||
// dispatcher_.fetchLabel(pattern->getDecl())});
|
||||
dispatcher_.emit(NamedPatternsTrap{label, pattern->getNameStr().str()});
|
||||
}
|
||||
|
||||
private:
|
||||
SwiftDispatcher& dispatcher;
|
||||
};
|
||||
void visitTypedPattern(swift::TypedPattern* pattern) {
|
||||
auto label = dispatcher_.assignNewLabel(pattern);
|
||||
assert(pattern->getSubPattern() && "expect TypedPattern to have a SubPattern");
|
||||
dispatcher_.emit(TypedPatternsTrap{label, dispatcher_.fetchLabel(pattern->getSubPattern())});
|
||||
if (auto typeRepr = pattern->getTypeRepr()) {
|
||||
dispatcher_.emit(
|
||||
TypedPatternTypeReprsTrap{label, dispatcher_.fetchLabel(pattern->getTypeRepr())});
|
||||
}
|
||||
}
|
||||
|
||||
void visitTuplePattern(swift::TuplePattern* pattern) {
|
||||
auto label = dispatcher_.assignNewLabel(pattern);
|
||||
dispatcher_.emit(TuplePatternsTrap{label});
|
||||
auto i = 0u;
|
||||
for (auto p : pattern->getElements()) {
|
||||
dispatcher_.emit(
|
||||
TuplePatternElementsTrap{label, i++, dispatcher_.fetchLabel(p.getPattern())});
|
||||
}
|
||||
}
|
||||
void visitAnyPattern(swift::AnyPattern* pattern) {
|
||||
dispatcher_.emit(AnyPatternsTrap{dispatcher_.assignNewLabel(pattern)});
|
||||
}
|
||||
|
||||
void visitBindingPattern(swift::BindingPattern* pattern) {
|
||||
auto label = dispatcher_.assignNewLabel(pattern);
|
||||
assert(pattern->getSubPattern() && "expect BindingPattern to have a SubPattern");
|
||||
dispatcher_.emit(BindingPatternsTrap{label, dispatcher_.fetchLabel(pattern->getSubPattern())});
|
||||
}
|
||||
|
||||
void visitEnumElementPattern(swift::EnumElementPattern* pattern) {
|
||||
auto label = dispatcher_.assignNewLabel(pattern);
|
||||
dispatcher_.emit(
|
||||
EnumElementPatternsTrap{label, dispatcher_.fetchLabel(pattern->getElementDecl())});
|
||||
if (auto subPattern = pattern->getSubPattern()) {
|
||||
dispatcher_.emit(EnumElementPatternSubPatternsTrap{
|
||||
label, dispatcher_.fetchLabel(pattern->getSubPattern())});
|
||||
}
|
||||
}
|
||||
|
||||
void visitOptionalSomePattern(swift::OptionalSomePattern* pattern) {
|
||||
auto label = dispatcher_.assignNewLabel(pattern);
|
||||
assert(pattern->getSubPattern() && "expect BindingPattern to have a SubPattern");
|
||||
dispatcher_.emit(
|
||||
OptionalSomePatternsTrap{label, dispatcher_.fetchLabel(pattern->getSubPattern())});
|
||||
}
|
||||
|
||||
void visitIsPattern(swift::IsPattern* pattern) {
|
||||
auto label = dispatcher_.assignNewLabel(pattern);
|
||||
dispatcher_.emit(IsPatternsTrap{label});
|
||||
|
||||
if (auto typeRepr = pattern->getCastTypeRepr()) {
|
||||
dispatcher_.emit(IsPatternCastTypeReprsTrap{label, dispatcher_.fetchLabel(typeRepr)});
|
||||
}
|
||||
if (auto subPattern = pattern->getSubPattern()) {
|
||||
dispatcher_.emit(IsPatternSubPatternsTrap{label, dispatcher_.fetchLabel(subPattern)});
|
||||
}
|
||||
}
|
||||
|
||||
void visitExprPattern(swift::ExprPattern* pattern) {
|
||||
auto label = dispatcher_.assignNewLabel(pattern);
|
||||
assert(pattern->getSubExpr() && "expect ExprPattern to have SubExpr");
|
||||
dispatcher_.emit(ExprPatternsTrap{label, dispatcher_.fetchLabel(pattern->getSubExpr())});
|
||||
}
|
||||
|
||||
void visitParenPattern(swift::ParenPattern* pattern) {
|
||||
auto label = dispatcher_.assignNewLabel(pattern);
|
||||
assert(pattern->getSubPattern() && "expect ParenPattern to have SubPattern");
|
||||
dispatcher_.emit(ParenPatternsTrap{label, dispatcher_.fetchLabel(pattern->getSubPattern())});
|
||||
}
|
||||
|
||||
void visitBoolPattern(swift::BoolPattern* pattern) {
|
||||
auto label = dispatcher_.assignNewLabel(pattern);
|
||||
dispatcher_.emit(BoolPatternsTrap{label, pattern->getValue()});
|
||||
}
|
||||
};
|
||||
} // namespace codeql
|
||||
|
||||
@@ -1,39 +1,223 @@
|
||||
#pragma once
|
||||
|
||||
#include "swift/extractor/SwiftDispatcher.h"
|
||||
#include <swift/AST/ASTVisitor.h>
|
||||
#include "swift/extractor/visitors/VisitorBase.h"
|
||||
|
||||
namespace codeql {
|
||||
|
||||
namespace detail {
|
||||
// swift code lacks default implementations of visitor for some entities. We can add those here
|
||||
// while we do not have yet all implemented. This is a simplified version of the corresponding Expr
|
||||
// code in swift/AST/ASTVisitor.h
|
||||
template <typename CrtpSubclass>
|
||||
class PatchedStmtVisitor : public swift::StmtVisitor<CrtpSubclass> {
|
||||
class StmtVisitor : public AstVisitorBase<StmtVisitor> {
|
||||
public:
|
||||
#define ABSTRACT_STMT(CLASS, PARENT) \
|
||||
void visit##CLASS##Stmt(swift::CLASS##Stmt* E) { \
|
||||
return static_cast<CrtpSubclass*>(this)->visit##PARENT(E); \
|
||||
using AstVisitorBase<StmtVisitor>::AstVisitorBase;
|
||||
|
||||
void visitLabeledStmt(swift::LabeledStmt* stmt) {
|
||||
auto label = dispatcher_.assignNewLabel(stmt);
|
||||
emitLabeledStmt(stmt, label);
|
||||
}
|
||||
#define STMT(CLASS, PARENT) ABSTRACT_STMT(CLASS, PARENT)
|
||||
#include "swift/AST/StmtNodes.def"
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
void visitStmtCondition(swift::StmtCondition* cond) {
|
||||
auto label = dispatcher_.assignNewLabel(cond);
|
||||
dispatcher_.emit(StmtConditionsTrap{label});
|
||||
unsigned index = 0;
|
||||
for (const auto& cond : *cond) {
|
||||
auto condLabel = dispatcher_.createLabel<ConditionElementTag>();
|
||||
dispatcher_.attachLocation(cond, condLabel);
|
||||
dispatcher_.emit(ConditionElementsTrap{condLabel});
|
||||
dispatcher_.emit(StmtConditionElementsTrap{label, index++, condLabel});
|
||||
if (auto boolean = cond.getBooleanOrNull()) {
|
||||
auto elementLabel = dispatcher_.fetchLabel(boolean);
|
||||
dispatcher_.emit(ConditionElementBooleansTrap{condLabel, elementLabel});
|
||||
} else if (auto pattern = cond.getPatternOrNull()) {
|
||||
auto patternLabel = dispatcher_.fetchLabel(pattern);
|
||||
auto initilizerLabel = dispatcher_.fetchLabel(cond.getInitializer());
|
||||
dispatcher_.emit(ConditionElementPatternsTrap{condLabel, patternLabel});
|
||||
dispatcher_.emit(ConditionElementInitializersTrap{condLabel, initilizerLabel});
|
||||
}
|
||||
/// TODO: Implement availability
|
||||
}
|
||||
}
|
||||
|
||||
class StmtVisitor : public detail::PatchedStmtVisitor<StmtVisitor> {
|
||||
public:
|
||||
// SwiftDispatcher should outlive the StmtVisitor
|
||||
StmtVisitor(SwiftDispatcher& dispatcher) : dispatcher(dispatcher) {}
|
||||
void visitLabeledConditionalStmt(swift::LabeledConditionalStmt* stmt) {
|
||||
auto label = dispatcher_.assignNewLabel(stmt);
|
||||
emitLabeledStmt(stmt, label);
|
||||
emitLabeledConditionalStmt(stmt, label);
|
||||
}
|
||||
|
||||
template <typename E>
|
||||
void visitStmt(E* stmt) {
|
||||
dispatcher.TBD<swift::Stmt>(stmt, "Stmt");
|
||||
void visitCaseLabelItem(swift::CaseLabelItem* labelItem) {
|
||||
auto label = dispatcher_.assignNewLabel(labelItem);
|
||||
assert(labelItem->getPattern() && "CaseLabelItem has Pattern");
|
||||
dispatcher_.emit(CaseLabelItemsTrap{label, dispatcher_.fetchLabel(labelItem->getPattern())});
|
||||
}
|
||||
|
||||
void visitBraceStmt(swift::BraceStmt* stmt) {
|
||||
auto label = dispatcher_.assignNewLabel(stmt);
|
||||
dispatcher_.emit(BraceStmtsTrap{label});
|
||||
auto i = 0u;
|
||||
for (auto& e : stmt->getElements()) {
|
||||
dispatcher_.emit(BraceStmtElementsTrap{label, i++, dispatcher_.fetchLabel(e)});
|
||||
}
|
||||
}
|
||||
|
||||
void visitReturnStmt(swift::ReturnStmt* stmt) {
|
||||
auto label = dispatcher_.assignNewLabel(stmt);
|
||||
dispatcher_.emit(ReturnStmtsTrap{label});
|
||||
if (stmt->hasResult()) {
|
||||
auto resultLabel = dispatcher_.fetchLabel(stmt->getResult());
|
||||
dispatcher_.emit(ReturnStmtResultsTrap{label, resultLabel});
|
||||
}
|
||||
}
|
||||
|
||||
void visitForEachStmt(swift::ForEachStmt* stmt) {
|
||||
auto label = dispatcher_.assignNewLabel(stmt);
|
||||
assert(stmt->getBody() && "ForEachStmt has getBody()");
|
||||
assert(stmt->getSequence() && "ForEachStmt has getSequence()");
|
||||
assert(stmt->getPattern() && "ForEachStmt has getPattern()");
|
||||
auto bodyLabel = dispatcher_.fetchLabel(stmt->getBody());
|
||||
auto sequenceLabel = dispatcher_.fetchLabel(stmt->getSequence());
|
||||
auto patternLabel = dispatcher_.fetchLabel(stmt->getPattern());
|
||||
emitLabeledStmt(stmt, label);
|
||||
dispatcher_.emit(ForEachStmtsTrap{label, patternLabel, sequenceLabel, bodyLabel});
|
||||
if (auto where = stmt->getWhere()) {
|
||||
auto whereLabel = dispatcher_.fetchLabel(where);
|
||||
dispatcher_.emit(ForEachStmtWheresTrap{label, whereLabel});
|
||||
}
|
||||
}
|
||||
|
||||
void visitIfStmt(swift::IfStmt* stmt) {
|
||||
auto label = dispatcher_.assignNewLabel(stmt);
|
||||
emitLabeledStmt(stmt, label);
|
||||
emitLabeledConditionalStmt(stmt, label);
|
||||
auto thenLabel = dispatcher_.fetchLabel(stmt->getThenStmt());
|
||||
dispatcher_.emit(IfStmtsTrap{label, thenLabel});
|
||||
if (auto* elseStmt = stmt->getElseStmt()) {
|
||||
auto elseLabel = dispatcher_.fetchLabel(elseStmt);
|
||||
dispatcher_.emit(IfStmtElsesTrap{label, elseLabel});
|
||||
}
|
||||
}
|
||||
|
||||
void visitBreakStmt(swift::BreakStmt* stmt) {
|
||||
auto label = dispatcher_.assignNewLabel(stmt);
|
||||
dispatcher_.emit(BreakStmtsTrap{label});
|
||||
if (auto* target = stmt->getTarget()) {
|
||||
auto targetlabel = dispatcher_.fetchLabel(target);
|
||||
dispatcher_.emit(BreakStmtTargetsTrap{label, targetlabel});
|
||||
}
|
||||
auto targetName = stmt->getTargetName();
|
||||
if (!targetName.empty()) {
|
||||
dispatcher_.emit(BreakStmtTargetNamesTrap{label, targetName.str().str()});
|
||||
}
|
||||
}
|
||||
|
||||
void visitContinueStmt(swift::ContinueStmt* stmt) {
|
||||
auto label = dispatcher_.assignNewLabel(stmt);
|
||||
dispatcher_.emit(ContinueStmtsTrap{label});
|
||||
if (auto* target = stmt->getTarget()) {
|
||||
auto targetlabel = dispatcher_.fetchLabel(target);
|
||||
dispatcher_.emit(ContinueStmtTargetsTrap{label, targetlabel});
|
||||
}
|
||||
auto targetName = stmt->getTargetName();
|
||||
if (!targetName.empty()) {
|
||||
dispatcher_.emit(ContinueStmtTargetNamesTrap{label, targetName.str().str()});
|
||||
}
|
||||
}
|
||||
|
||||
void visitWhileStmt(swift::WhileStmt* stmt) {
|
||||
auto label = dispatcher_.assignNewLabel(stmt);
|
||||
emitLabeledStmt(stmt, label);
|
||||
emitLabeledConditionalStmt(stmt, label);
|
||||
dispatcher_.emit(WhileStmtsTrap{label, dispatcher_.fetchLabel(stmt->getBody())});
|
||||
}
|
||||
|
||||
void visitRepeatWhileStmt(swift::RepeatWhileStmt* stmt) {
|
||||
auto label = dispatcher_.assignNewLabel(stmt);
|
||||
emitLabeledStmt(stmt, label);
|
||||
auto bodyLabel = dispatcher_.fetchLabel(stmt->getBody());
|
||||
auto condLabel = dispatcher_.fetchLabel(stmt->getCond());
|
||||
dispatcher_.emit(RepeatWhileStmtsTrap{label, condLabel, bodyLabel});
|
||||
}
|
||||
|
||||
void visitDoCatchStmt(swift::DoCatchStmt* stmt) {
|
||||
auto label = dispatcher_.assignNewLabel(stmt);
|
||||
emitLabeledStmt(stmt, label);
|
||||
auto bodyLabel = dispatcher_.fetchLabel(stmt->getBody());
|
||||
dispatcher_.emit(DoCatchStmtsTrap{label, bodyLabel});
|
||||
auto i = 0u;
|
||||
for (auto* stmtCatch : stmt->getCatches()) {
|
||||
dispatcher_.emit(DoCatchStmtCatchesTrap{label, i++, dispatcher_.fetchLabel(stmtCatch)});
|
||||
}
|
||||
}
|
||||
|
||||
void visitCaseStmt(swift::CaseStmt* stmt) {
|
||||
auto label = dispatcher_.assignNewLabel(stmt);
|
||||
auto bodyLabel = dispatcher_.fetchLabel(stmt->getBody());
|
||||
dispatcher_.emit(CaseStmtsTrap{label, bodyLabel});
|
||||
auto i = 0u;
|
||||
for (auto& item : stmt->getMutableCaseLabelItems()) {
|
||||
dispatcher_.emit(CaseStmtLabelsTrap{label, i++, dispatcher_.fetchLabel(&item)});
|
||||
}
|
||||
if (stmt->hasCaseBodyVariables()) {
|
||||
auto i = 0u;
|
||||
for (auto* var : stmt->getCaseBodyVariables()) {
|
||||
dispatcher_.emit(CaseStmtVariablesTrap{label, i++, dispatcher_.fetchLabel(var)});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void visitGuardStmt(swift::GuardStmt* stmt) {
|
||||
auto label = dispatcher_.assignNewLabel(stmt);
|
||||
emitLabeledStmt(stmt, label);
|
||||
emitLabeledConditionalStmt(stmt, label);
|
||||
auto bodyLabel = dispatcher_.fetchLabel(stmt->getBody());
|
||||
dispatcher_.emit(GuardStmtsTrap{label, bodyLabel});
|
||||
}
|
||||
|
||||
void visitThrowStmt(swift::ThrowStmt* stmt) {
|
||||
auto label = dispatcher_.assignNewLabel(stmt);
|
||||
auto subExprLabel = dispatcher_.fetchLabel(stmt->getSubExpr());
|
||||
dispatcher_.emit(ThrowStmtsTrap{label, subExprLabel});
|
||||
}
|
||||
|
||||
void visitDeferStmt(swift::DeferStmt* stmt) {
|
||||
auto label = dispatcher_.assignNewLabel(stmt);
|
||||
auto bodyLabel = dispatcher_.fetchLabel(stmt->getBodyAsWritten());
|
||||
dispatcher_.emit(DeferStmtsTrap{label, bodyLabel});
|
||||
}
|
||||
|
||||
void visitDoStmt(swift::DoStmt* stmt) {
|
||||
auto label = dispatcher_.assignNewLabel(stmt);
|
||||
emitLabeledStmt(stmt, label);
|
||||
auto bodyLabel = dispatcher_.fetchLabel(stmt->getBody());
|
||||
dispatcher_.emit(DoStmtsTrap{label, bodyLabel});
|
||||
}
|
||||
|
||||
void visitSwitchStmt(swift::SwitchStmt* stmt) {
|
||||
auto label = dispatcher_.assignNewLabel(stmt);
|
||||
emitLabeledStmt(stmt, label);
|
||||
auto subjectLabel = dispatcher_.fetchLabel(stmt->getSubjectExpr());
|
||||
dispatcher_.emit(SwitchStmtsTrap{label, subjectLabel});
|
||||
auto i = 0u;
|
||||
for (auto* c : stmt->getCases()) {
|
||||
dispatcher_.emit(SwitchStmtCasesTrap{label, i++, dispatcher_.fetchLabel(c)});
|
||||
}
|
||||
}
|
||||
|
||||
void visitFallthroughStmt(swift::FallthroughStmt* stmt) {
|
||||
auto label = dispatcher_.assignNewLabel(stmt);
|
||||
auto sourceLabel = dispatcher_.fetchLabel(stmt->getFallthroughSource());
|
||||
auto destLabel = dispatcher_.fetchLabel(stmt->getFallthroughDest());
|
||||
dispatcher_.emit(FallthroughStmtsTrap{label, sourceLabel, destLabel});
|
||||
}
|
||||
|
||||
private:
|
||||
SwiftDispatcher& dispatcher;
|
||||
void emitLabeledStmt(const swift::LabeledStmt* stmt, TrapLabel<LabeledStmtTag> label) {
|
||||
if (stmt->getLabelInfo()) {
|
||||
dispatcher_.emit(LabeledStmtLabelsTrap{label, stmt->getLabelInfo().Name.str().str()});
|
||||
}
|
||||
}
|
||||
|
||||
void emitLabeledConditionalStmt(swift::LabeledConditionalStmt* stmt,
|
||||
TrapLabel<LabeledConditionalStmtTag> label) {
|
||||
auto condLabel = dispatcher_.fetchLabel(stmt->getCondPointer());
|
||||
dispatcher_.emit(LabeledConditionalStmtsTrap{label, condLabel});
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace codeql
|
||||
|
||||
12
swift/extractor/visitors/TypeReprVisitor.h
Normal file
12
swift/extractor/visitors/TypeReprVisitor.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "swift/extractor/visitors/VisitorBase.h"
|
||||
|
||||
namespace codeql {
|
||||
|
||||
class TypeReprVisitor : public AstVisitorBase<TypeReprVisitor> {
|
||||
public:
|
||||
using AstVisitorBase<TypeReprVisitor>::AstVisitorBase;
|
||||
};
|
||||
|
||||
} // namespace codeql
|
||||
@@ -1,22 +1,233 @@
|
||||
#pragma once
|
||||
|
||||
#include "swift/extractor/SwiftDispatcher.h"
|
||||
#include <swift/AST/TypeVisitor.h>
|
||||
|
||||
#include "swift/extractor/visitors/VisitorBase.h"
|
||||
namespace codeql {
|
||||
|
||||
class TypeVisitor : public swift::TypeVisitor<TypeVisitor> {
|
||||
class TypeVisitor : public TypeVisitorBase<TypeVisitor> {
|
||||
public:
|
||||
// SwiftDispatcher should outlive the TypeVisitor
|
||||
TypeVisitor(SwiftDispatcher& dispatcher) : dispatcher(dispatcher) {}
|
||||
using TypeVisitorBase<TypeVisitor>::TypeVisitorBase;
|
||||
|
||||
template <typename E>
|
||||
void visitType(E* type) {
|
||||
dispatcher.TBD<swift::TypeBase>(type, "Type");
|
||||
void visit(swift::TypeBase* type) {
|
||||
TypeVisitorBase<TypeVisitor>::visit(type);
|
||||
auto label = dispatcher_.fetchLabel(type);
|
||||
auto canonical = type->getCanonicalType().getPointer();
|
||||
auto canonicalLabel = (canonical == type) ? label : dispatcher_.fetchLabel(canonical);
|
||||
dispatcher_.emit(TypesTrap{label, type->getString(), canonicalLabel});
|
||||
}
|
||||
|
||||
void visitProtocolType(swift::ProtocolType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
dispatcher_.emit(ProtocolTypesTrap{label});
|
||||
emitAnyGenericType(type, label);
|
||||
}
|
||||
|
||||
void visitEnumType(swift::EnumType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
dispatcher_.emit(EnumTypesTrap{label});
|
||||
emitAnyGenericType(type, label);
|
||||
}
|
||||
|
||||
void visitStructType(swift::StructType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
dispatcher_.emit(StructTypesTrap{label});
|
||||
emitAnyGenericType(type, label);
|
||||
}
|
||||
|
||||
void visitClassType(swift::ClassType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
dispatcher_.emit(ClassTypesTrap{label});
|
||||
emitAnyGenericType(type, label);
|
||||
}
|
||||
|
||||
void visitFunctionType(swift::FunctionType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
dispatcher_.emit(FunctionTypesTrap{label});
|
||||
emitAnyFunctionType(type, label);
|
||||
}
|
||||
|
||||
void visitTupleType(swift::TupleType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
dispatcher_.emit(TupleTypesTrap{label});
|
||||
auto i = 0u;
|
||||
for (const auto& e : type->getElements()) {
|
||||
auto typeTag = dispatcher_.fetchLabel(e.getType());
|
||||
dispatcher_.emit(TupleTypeTypesTrap{label, i, typeTag});
|
||||
if (e.hasName()) {
|
||||
dispatcher_.emit(TupleTypeNamesTrap{label, i, e.getName().str().str()});
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
void visitBoundGenericEnumType(swift::BoundGenericEnumType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
dispatcher_.emit(BoundGenericEnumTypesTrap{label});
|
||||
emitBoundGenericType(type, label);
|
||||
}
|
||||
|
||||
void visitMetatypeType(swift::MetatypeType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
dispatcher_.emit(MetatypeTypesTrap{label});
|
||||
}
|
||||
|
||||
void visitExistentialMetatypeType(swift::ExistentialMetatypeType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
dispatcher_.emit(ExistentialMetatypeTypesTrap{label});
|
||||
}
|
||||
|
||||
void visitBoundGenericStructType(swift::BoundGenericStructType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
dispatcher_.emit(BoundGenericStructTypesTrap{label});
|
||||
emitBoundGenericType(type, label);
|
||||
}
|
||||
|
||||
void visitTypeAliasType(swift::TypeAliasType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
assert(type->getDecl() && "expect TypeAliasType to have Decl");
|
||||
dispatcher_.emit(TypeAliasTypesTrap{label, dispatcher_.fetchLabel(type->getDecl())});
|
||||
}
|
||||
|
||||
void visitBuiltinIntegerLiteralType(swift::BuiltinIntegerLiteralType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
dispatcher_.emit(BuiltinIntegerLiteralTypesTrap{label});
|
||||
}
|
||||
|
||||
void visitBuiltinFloatType(swift::BuiltinFloatType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
dispatcher_.emit(BuiltinFloatTypesTrap{label});
|
||||
}
|
||||
|
||||
void visitBuiltinIntegerType(swift::BuiltinIntegerType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
auto width = type->getWidth();
|
||||
if (width.isFixedWidth()) {
|
||||
dispatcher_.emit(BuiltinIntegerTypeWidthsTrap{label, width.getFixedWidth()});
|
||||
}
|
||||
dispatcher_.emit(BuiltinIntegerTypesTrap{label});
|
||||
}
|
||||
|
||||
void visitBoundGenericClassType(swift::BoundGenericClassType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
dispatcher_.emit(BoundGenericClassTypesTrap{label});
|
||||
emitBoundGenericType(type, label);
|
||||
}
|
||||
|
||||
void visitDependentMemberType(swift::DependentMemberType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
assert(type->getBase() && "expect TypeAliasType to have Base");
|
||||
assert(type->getAssocType() && "expect TypeAliasType to have AssocType");
|
||||
auto baseLabel = dispatcher_.fetchLabel(type->getBase());
|
||||
auto assocTypeDeclLabel = dispatcher_.fetchLabel(type->getAssocType());
|
||||
dispatcher_.emit(DependentMemberTypesTrap{label, baseLabel, assocTypeDeclLabel});
|
||||
}
|
||||
|
||||
void visitParenType(swift::ParenType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
assert(type->getUnderlyingType() && "expect ParenType to have UnderlyingType");
|
||||
auto typeLabel = dispatcher_.fetchLabel(type->getUnderlyingType());
|
||||
dispatcher_.emit(ParenTypesTrap{label, typeLabel});
|
||||
}
|
||||
|
||||
void visitUnarySyntaxSugarType(swift::UnarySyntaxSugarType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
emitUnarySyntaxSugarType(type, label);
|
||||
}
|
||||
|
||||
void visitOptionalType(swift::OptionalType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
dispatcher_.emit(OptionalTypesTrap{label});
|
||||
emitUnarySyntaxSugarType(type, label);
|
||||
}
|
||||
|
||||
void visitArraySliceType(swift::ArraySliceType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
dispatcher_.emit(ArraySliceTypesTrap{label});
|
||||
emitUnarySyntaxSugarType(type, label);
|
||||
}
|
||||
|
||||
void visitDictionaryType(swift::DictionaryType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
auto keyLabel = dispatcher_.fetchLabel(type->getKeyType());
|
||||
auto valueLabel = dispatcher_.fetchLabel(type->getValueType());
|
||||
dispatcher_.emit(DictionaryTypesTrap{label, keyLabel, valueLabel});
|
||||
}
|
||||
|
||||
void visitGenericFunctionType(swift::GenericFunctionType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
dispatcher_.emit(GenericFunctionTypesTrap{label});
|
||||
emitAnyFunctionType(type, label);
|
||||
auto i = 0u;
|
||||
for (auto p : type->getGenericParams()) {
|
||||
dispatcher_.emit(GenericFunctionTypeGenericParamsTrap{label, i++, dispatcher_.fetchLabel(p)});
|
||||
}
|
||||
}
|
||||
|
||||
void visitGenericTypeParamType(swift::GenericTypeParamType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
dispatcher_.emit(GenericTypeParamTypesTrap{label, type->getName().str().str()});
|
||||
}
|
||||
|
||||
void visitLValueType(swift::LValueType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
assert(type->getObjectType() && "expect LValueType to have ObjectType");
|
||||
dispatcher_.emit(LValueTypesTrap{label, dispatcher_.fetchLabel(type->getObjectType())});
|
||||
}
|
||||
|
||||
void visitPrimaryArchetypeType(swift::PrimaryArchetypeType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
assert(type->getInterfaceType() && "expect PrimaryArchetypeType to have InterfaceType");
|
||||
dispatcher_.emit(
|
||||
PrimaryArchetypeTypesTrap{label, dispatcher_.fetchLabel(type->getInterfaceType())});
|
||||
}
|
||||
|
||||
void visitUnboundGenericType(swift::UnboundGenericType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
dispatcher_.emit(UnboundGenericTypesTrap{label});
|
||||
emitAnyGenericType(type, label);
|
||||
}
|
||||
|
||||
void visitBoundGenericType(swift::BoundGenericType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
emitBoundGenericType(type, label);
|
||||
}
|
||||
|
||||
private:
|
||||
SwiftDispatcher& dispatcher;
|
||||
void emitUnarySyntaxSugarType(const swift::UnarySyntaxSugarType* type,
|
||||
TrapLabel<UnarySyntaxSugarTypeTag> label) {
|
||||
assert(type->getBaseType() && "expect UnarySyntaxSugarType to have BaseType");
|
||||
dispatcher_.emit(UnarySyntaxSugarTypesTrap{label, dispatcher_.fetchLabel(type->getBaseType())});
|
||||
}
|
||||
|
||||
void emitAnyFunctionType(const swift::AnyFunctionType* type,
|
||||
TrapLabel<AnyFunctionTypeTag> label) {
|
||||
assert(type->getResult() && "expect FunctionType to have Result");
|
||||
dispatcher_.emit(AnyFunctionTypesTrap{label, dispatcher_.fetchLabel(type->getResult())});
|
||||
auto i = 0u;
|
||||
for (const auto& p : type->getParams()) {
|
||||
assert(p.getPlainType() && "expect Param to have PlainType");
|
||||
dispatcher_.emit(
|
||||
AnyFunctionTypeParamTypesTrap{label, i, dispatcher_.fetchLabel(p.getPlainType())});
|
||||
if (p.hasLabel()) {
|
||||
dispatcher_.emit(AnyFunctionTypeParamLabelsTrap{label, i, p.getLabel().str().str()});
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
void emitBoundGenericType(swift::BoundGenericType* type, TrapLabel<BoundGenericTypeTag> label) {
|
||||
auto i = 0u;
|
||||
for (const auto& t : type->getGenericArgs()) {
|
||||
dispatcher_.emit(BoundGenericTypeArgTypesTrap{label, i++, dispatcher_.fetchLabel(t)});
|
||||
}
|
||||
emitAnyGenericType(type, label);
|
||||
}
|
||||
|
||||
void emitAnyGenericType(swift::AnyGenericType* type, TrapLabel<AnyGenericTypeTag> label) {
|
||||
assert(type->getDecl() && "expect AnyGenericType to have Decl");
|
||||
dispatcher_.emit(AnyGenericTypesTrap{label, dispatcher_.fetchLabel(type->getDecl())});
|
||||
if (auto parent = type->getParent()) {
|
||||
dispatcher_.emit(AnyGenericTypeParentsTrap{label, dispatcher_.fetchLabel(parent)});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace codeql
|
||||
|
||||
65
swift/extractor/visitors/VisitorBase.h
Normal file
65
swift/extractor/visitors/VisitorBase.h
Normal file
@@ -0,0 +1,65 @@
|
||||
#pragma once
|
||||
|
||||
#include <swift/AST/ASTVisitor.h>
|
||||
#include <swift/AST/TypeVisitor.h>
|
||||
|
||||
#include "swift/extractor/SwiftDispatcher.h"
|
||||
|
||||
namespace codeql {
|
||||
|
||||
namespace detail {
|
||||
class VisitorBase {
|
||||
protected:
|
||||
SwiftDispatcher& dispatcher_;
|
||||
|
||||
public:
|
||||
// SwiftDispatcher should outlive this instance
|
||||
VisitorBase(SwiftDispatcher& dispatcher) : dispatcher_{dispatcher} {}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// we want to override the default swift visitor behaviour of chaining calls to immediate
|
||||
// superclasses by default and instead provide our own TBD default (using the exact type)
|
||||
#define DEFAULT(KIND, CLASS, PARENT) \
|
||||
void visit##CLASS##KIND(swift::CLASS##KIND* e) { dispatcher_.emitUnknown(e); }
|
||||
|
||||
// base class for our AST visitors, getting a SwiftDispatcher member and default emission for
|
||||
// unknown/TBD entities. Like `swift::ASTVisitor`, this uses CRTP (the Curiously Recurring Template
|
||||
// Pattern)
|
||||
template <typename CrtpSubclass>
|
||||
class AstVisitorBase : public swift::ASTVisitor<CrtpSubclass>, protected detail::VisitorBase {
|
||||
public:
|
||||
using VisitorBase::VisitorBase;
|
||||
|
||||
#define DECL(CLASS, PARENT) DEFAULT(Decl, CLASS, PARENT)
|
||||
#include "swift/AST/DeclNodes.def"
|
||||
|
||||
#define STMT(CLASS, PARENT) DEFAULT(Stmt, CLASS, PARENT)
|
||||
#include "swift/AST/StmtNodes.def"
|
||||
|
||||
#define EXPR(CLASS, PARENT) DEFAULT(Expr, CLASS, PARENT)
|
||||
#include "swift/AST/ExprNodes.def"
|
||||
|
||||
#define PATTERN(CLASS, PARENT) DEFAULT(Pattern, CLASS, PARENT)
|
||||
#include "swift/AST/PatternNodes.def"
|
||||
|
||||
#define TYPEREPR(CLASS, PARENT) DEFAULT(TypeRepr, CLASS, PARENT)
|
||||
#include "swift/AST/TypeReprNodes.def"
|
||||
};
|
||||
|
||||
// base class for our type visitor, getting a SwiftDispatcher member and default emission for
|
||||
// unknown/TBD types. Like `swift::TypeVisitor`, this uses CRTP (the Curiously Recurring Template
|
||||
// Pattern)
|
||||
template <typename CrtpSubclass>
|
||||
class TypeVisitorBase : public swift::TypeVisitor<CrtpSubclass>, protected detail::VisitorBase {
|
||||
public:
|
||||
using VisitorBase::VisitorBase;
|
||||
|
||||
#define TYPE(CLASS, PARENT) DEFAULT(Type, CLASS, PARENT)
|
||||
#include "swift/AST/TypeNodes.def"
|
||||
};
|
||||
|
||||
#undef DEFAULT
|
||||
|
||||
} // namespace codeql
|
||||
@@ -19,10 +19,12 @@ import codeql.swift.elements.expr.Argument
|
||||
import codeql.swift.elements.expr.ArrayExpr
|
||||
import codeql.swift.elements.type.ArraySliceType
|
||||
import codeql.swift.elements.expr.ArrayToPointerExpr
|
||||
import codeql.swift.elements.typerepr.ArrayTypeRepr
|
||||
import codeql.swift.elements.expr.ArrowExpr
|
||||
import codeql.swift.elements.expr.AssignExpr
|
||||
import codeql.swift.elements.decl.AssociatedTypeDecl
|
||||
import codeql.swift.elements.AstNode
|
||||
import codeql.swift.elements.typerepr.AttributedTypeRepr
|
||||
import codeql.swift.elements.expr.AutoClosureExpr
|
||||
import codeql.swift.elements.expr.AwaitExpr
|
||||
import codeql.swift.elements.expr.BinaryExpr
|
||||
@@ -65,6 +67,10 @@ import codeql.swift.elements.expr.CodeCompletionExpr
|
||||
import codeql.swift.elements.expr.CoerceExpr
|
||||
import codeql.swift.elements.expr.CollectionExpr
|
||||
import codeql.swift.elements.expr.CollectionUpcastConversionExpr
|
||||
import codeql.swift.elements.typerepr.CompileTimeConstTypeRepr
|
||||
import codeql.swift.elements.typerepr.ComponentIdentTypeRepr
|
||||
import codeql.swift.elements.typerepr.CompositionTypeRepr
|
||||
import codeql.swift.elements.typerepr.CompoundIdentTypeRepr
|
||||
import codeql.swift.elements.decl.ConcreteFuncDecl
|
||||
import codeql.swift.elements.decl.ConcreteVarDecl
|
||||
import codeql.swift.elements.stmt.ConditionElement
|
||||
@@ -85,6 +91,7 @@ import codeql.swift.elements.decl.DestructorDecl
|
||||
import codeql.swift.elements.expr.DestructureTupleExpr
|
||||
import codeql.swift.elements.expr.DictionaryExpr
|
||||
import codeql.swift.elements.type.DictionaryType
|
||||
import codeql.swift.elements.typerepr.DictionaryTypeRepr
|
||||
import codeql.swift.elements.expr.DifferentiableFunctionExpr
|
||||
import codeql.swift.elements.expr.DifferentiableFunctionExtractOriginalExpr
|
||||
import codeql.swift.elements.expr.DiscardAssignmentExpr
|
||||
@@ -109,9 +116,11 @@ import codeql.swift.elements.type.EnumType
|
||||
import codeql.swift.elements.expr.ErasureExpr
|
||||
import codeql.swift.elements.expr.ErrorExpr
|
||||
import codeql.swift.elements.type.ErrorType
|
||||
import codeql.swift.elements.typerepr.ErrorTypeRepr
|
||||
import codeql.swift.elements.expr.ExistentialMetatypeToObjectExpr
|
||||
import codeql.swift.elements.type.ExistentialMetatypeType
|
||||
import codeql.swift.elements.type.ExistentialType
|
||||
import codeql.swift.elements.typerepr.ExistentialTypeRepr
|
||||
import codeql.swift.elements.expr.ExplicitCastExpr
|
||||
import codeql.swift.elements.expr.Expr
|
||||
import codeql.swift.elements.pattern.ExprPattern
|
||||
@@ -119,6 +128,7 @@ import codeql.swift.elements.decl.ExtensionDecl
|
||||
import codeql.swift.elements.stmt.FailStmt
|
||||
import codeql.swift.elements.stmt.FallthroughStmt
|
||||
import codeql.swift.elements.File
|
||||
import codeql.swift.elements.typerepr.FixedTypeRepr
|
||||
import codeql.swift.elements.expr.FloatLiteralExpr
|
||||
import codeql.swift.elements.stmt.ForEachStmt
|
||||
import codeql.swift.elements.expr.ForceTryExpr
|
||||
@@ -128,27 +138,33 @@ import codeql.swift.elements.expr.ForeignObjectConversionExpr
|
||||
import codeql.swift.elements.decl.FuncDecl
|
||||
import codeql.swift.elements.expr.FunctionConversionExpr
|
||||
import codeql.swift.elements.type.FunctionType
|
||||
import codeql.swift.elements.typerepr.FunctionTypeRepr
|
||||
import codeql.swift.elements.decl.GenericContext
|
||||
import codeql.swift.elements.type.GenericFunctionType
|
||||
import codeql.swift.elements.typerepr.GenericIdentTypeRepr
|
||||
import codeql.swift.elements.decl.GenericTypeDecl
|
||||
import codeql.swift.elements.decl.GenericTypeParamDecl
|
||||
import codeql.swift.elements.type.GenericTypeParamType
|
||||
import codeql.swift.elements.stmt.GuardStmt
|
||||
import codeql.swift.elements.typerepr.IdentTypeRepr
|
||||
import codeql.swift.elements.expr.IdentityExpr
|
||||
import codeql.swift.elements.decl.IfConfigDecl
|
||||
import codeql.swift.elements.expr.IfExpr
|
||||
import codeql.swift.elements.stmt.IfStmt
|
||||
import codeql.swift.elements.expr.ImplicitConversionExpr
|
||||
import codeql.swift.elements.typerepr.ImplicitlyUnwrappedOptionalTypeRepr
|
||||
import codeql.swift.elements.decl.ImportDecl
|
||||
import codeql.swift.elements.expr.InOutExpr
|
||||
import codeql.swift.elements.expr.InOutToPointerExpr
|
||||
import codeql.swift.elements.type.InOutType
|
||||
import codeql.swift.elements.typerepr.InOutTypeRepr
|
||||
import codeql.swift.elements.decl.InfixOperatorDecl
|
||||
import codeql.swift.elements.expr.InjectIntoOptionalExpr
|
||||
import codeql.swift.elements.expr.IntegerLiteralExpr
|
||||
import codeql.swift.elements.expr.InterpolatedStringLiteralExpr
|
||||
import codeql.swift.elements.expr.IsExpr
|
||||
import codeql.swift.elements.pattern.IsPattern
|
||||
import codeql.swift.elements.typerepr.IsolatedTypeRepr
|
||||
import codeql.swift.elements.decl.IterableDeclContext
|
||||
import codeql.swift.elements.expr.KeyPathApplicationExpr
|
||||
import codeql.swift.elements.expr.KeyPathDotExpr
|
||||
@@ -170,9 +186,11 @@ import codeql.swift.elements.expr.MakeTemporarilyEscapableExpr
|
||||
import codeql.swift.elements.expr.MemberRefExpr
|
||||
import codeql.swift.elements.expr.MetatypeConversionExpr
|
||||
import codeql.swift.elements.type.MetatypeType
|
||||
import codeql.swift.elements.typerepr.MetatypeTypeRepr
|
||||
import codeql.swift.elements.decl.MissingMemberDecl
|
||||
import codeql.swift.elements.decl.ModuleDecl
|
||||
import codeql.swift.elements.type.ModuleType
|
||||
import codeql.swift.elements.typerepr.NamedOpaqueReturnTypeRepr
|
||||
import codeql.swift.elements.pattern.NamedPattern
|
||||
import codeql.swift.elements.type.NestedArchetypeType
|
||||
import codeql.swift.elements.expr.NilLiteralExpr
|
||||
@@ -183,6 +201,7 @@ import codeql.swift.elements.expr.NumberLiteralExpr
|
||||
import codeql.swift.elements.expr.ObjCSelectorExpr
|
||||
import codeql.swift.elements.expr.ObjectLiteralExpr
|
||||
import codeql.swift.elements.expr.OneWayExpr
|
||||
import codeql.swift.elements.typerepr.OpaqueReturnTypeRepr
|
||||
import codeql.swift.elements.type.OpaqueTypeArchetypeType
|
||||
import codeql.swift.elements.decl.OpaqueTypeDecl
|
||||
import codeql.swift.elements.expr.OpaqueValueExpr
|
||||
@@ -193,9 +212,11 @@ import codeql.swift.elements.expr.OptionalEvaluationExpr
|
||||
import codeql.swift.elements.pattern.OptionalSomePattern
|
||||
import codeql.swift.elements.expr.OptionalTryExpr
|
||||
import codeql.swift.elements.type.OptionalType
|
||||
import codeql.swift.elements.typerepr.OptionalTypeRepr
|
||||
import codeql.swift.elements.expr.OtherConstructorDeclRefExpr
|
||||
import codeql.swift.elements.expr.OverloadSetRefExpr
|
||||
import codeql.swift.elements.expr.OverloadedDeclRefExpr
|
||||
import codeql.swift.elements.typerepr.OwnedTypeRepr
|
||||
import codeql.swift.elements.decl.ParamDecl
|
||||
import codeql.swift.elements.expr.ParenExpr
|
||||
import codeql.swift.elements.pattern.ParenPattern
|
||||
@@ -203,6 +224,7 @@ import codeql.swift.elements.type.ParenType
|
||||
import codeql.swift.elements.pattern.Pattern
|
||||
import codeql.swift.elements.decl.PatternBindingDecl
|
||||
import codeql.swift.elements.type.PlaceholderType
|
||||
import codeql.swift.elements.typerepr.PlaceholderTypeRepr
|
||||
import codeql.swift.elements.expr.PointerToPointerExpr
|
||||
import codeql.swift.elements.decl.PostfixOperatorDecl
|
||||
import codeql.swift.elements.expr.PostfixUnaryExpr
|
||||
@@ -217,6 +239,7 @@ import codeql.swift.elements.type.ProtocolCompositionType
|
||||
import codeql.swift.elements.decl.ProtocolDecl
|
||||
import codeql.swift.elements.expr.ProtocolMetatypeToObjectExpr
|
||||
import codeql.swift.elements.type.ProtocolType
|
||||
import codeql.swift.elements.typerepr.ProtocolTypeRepr
|
||||
import codeql.swift.elements.expr.RebindSelfInConstructorExpr
|
||||
import codeql.swift.elements.type.ReferenceStorageType
|
||||
import codeql.swift.elements.expr.RegexLiteralExpr
|
||||
@@ -225,10 +248,14 @@ import codeql.swift.elements.stmt.ReturnStmt
|
||||
import codeql.swift.elements.expr.SelfApplyExpr
|
||||
import codeql.swift.elements.type.SequenceArchetypeType
|
||||
import codeql.swift.elements.expr.SequenceExpr
|
||||
import codeql.swift.elements.typerepr.SharedTypeRepr
|
||||
import codeql.swift.elements.type.SilBlockStorageType
|
||||
import codeql.swift.elements.type.SilBoxType
|
||||
import codeql.swift.elements.typerepr.SilBoxTypeRepr
|
||||
import codeql.swift.elements.type.SilFunctionType
|
||||
import codeql.swift.elements.type.SilTokenType
|
||||
import codeql.swift.elements.typerepr.SimpleIdentTypeRepr
|
||||
import codeql.swift.elements.typerepr.SpecifierTypeRepr
|
||||
import codeql.swift.elements.stmt.Stmt
|
||||
import codeql.swift.elements.stmt.StmtCondition
|
||||
import codeql.swift.elements.expr.StringLiteralExpr
|
||||
@@ -250,6 +277,7 @@ import codeql.swift.elements.expr.TupleElementExpr
|
||||
import codeql.swift.elements.expr.TupleExpr
|
||||
import codeql.swift.elements.pattern.TuplePattern
|
||||
import codeql.swift.elements.type.TupleType
|
||||
import codeql.swift.elements.typerepr.TupleTypeRepr
|
||||
import codeql.swift.elements.type.Type
|
||||
import codeql.swift.elements.decl.TypeAliasDecl
|
||||
import codeql.swift.elements.type.TypeAliasType
|
||||
@@ -262,8 +290,6 @@ import codeql.swift.elements.type.UnarySyntaxSugarType
|
||||
import codeql.swift.elements.type.UnboundGenericType
|
||||
import codeql.swift.elements.expr.UnderlyingToOpaqueExpr
|
||||
import codeql.swift.elements.expr.UnevaluatedInstanceExpr
|
||||
import codeql.swift.elements.UnknownAstNode
|
||||
import codeql.swift.elements.type.UnknownType
|
||||
import codeql.swift.elements.type.UnmanagedStorageType
|
||||
import codeql.swift.elements.type.UnownedStorageType
|
||||
import codeql.swift.elements.expr.UnresolvedDeclRefExpr
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
|
||||
private import codeql.swift.generated.Element
|
||||
|
||||
class Element extends ElementBase { }
|
||||
class Element extends ElementBase {
|
||||
override string toString() { result = getPrimaryQlClasses() }
|
||||
}
|
||||
|
||||
class UnknownElement extends Element {
|
||||
UnknownElement() { isUnknown() }
|
||||
|
||||
override string toString() { result = "TBD (" + getPrimaryQlClasses() + ")" }
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
private import codeql.swift.generated.UnknownAstNode
|
||||
|
||||
class UnknownAstNode extends UnknownAstNodeBase {
|
||||
override string toString() { result = getName() }
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
|
||||
private import codeql.swift.generated.type.UnknownType
|
||||
|
||||
class UnknownType extends UnknownTypeBase { }
|
||||
@@ -0,0 +1,4 @@
|
||||
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
|
||||
private import codeql.swift.generated.typerepr.ArrayTypeRepr
|
||||
|
||||
class ArrayTypeRepr extends ArrayTypeReprBase { }
|
||||
@@ -0,0 +1,4 @@
|
||||
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
|
||||
private import codeql.swift.generated.typerepr.AttributedTypeRepr
|
||||
|
||||
class AttributedTypeRepr extends AttributedTypeReprBase { }
|
||||
@@ -0,0 +1,4 @@
|
||||
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
|
||||
private import codeql.swift.generated.typerepr.CompileTimeConstTypeRepr
|
||||
|
||||
class CompileTimeConstTypeRepr extends CompileTimeConstTypeReprBase { }
|
||||
@@ -0,0 +1,4 @@
|
||||
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
|
||||
private import codeql.swift.generated.typerepr.ComponentIdentTypeRepr
|
||||
|
||||
class ComponentIdentTypeRepr extends ComponentIdentTypeReprBase { }
|
||||
@@ -0,0 +1,4 @@
|
||||
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
|
||||
private import codeql.swift.generated.typerepr.CompositionTypeRepr
|
||||
|
||||
class CompositionTypeRepr extends CompositionTypeReprBase { }
|
||||
@@ -0,0 +1,4 @@
|
||||
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
|
||||
private import codeql.swift.generated.typerepr.CompoundIdentTypeRepr
|
||||
|
||||
class CompoundIdentTypeRepr extends CompoundIdentTypeReprBase { }
|
||||
@@ -0,0 +1,4 @@
|
||||
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
|
||||
private import codeql.swift.generated.typerepr.DictionaryTypeRepr
|
||||
|
||||
class DictionaryTypeRepr extends DictionaryTypeReprBase { }
|
||||
@@ -0,0 +1,4 @@
|
||||
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
|
||||
private import codeql.swift.generated.typerepr.ErrorTypeRepr
|
||||
|
||||
class ErrorTypeRepr extends ErrorTypeReprBase { }
|
||||
@@ -0,0 +1,4 @@
|
||||
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
|
||||
private import codeql.swift.generated.typerepr.ExistentialTypeRepr
|
||||
|
||||
class ExistentialTypeRepr extends ExistentialTypeReprBase { }
|
||||
@@ -0,0 +1,4 @@
|
||||
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
|
||||
private import codeql.swift.generated.typerepr.FixedTypeRepr
|
||||
|
||||
class FixedTypeRepr extends FixedTypeReprBase { }
|
||||
@@ -0,0 +1,4 @@
|
||||
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
|
||||
private import codeql.swift.generated.typerepr.FunctionTypeRepr
|
||||
|
||||
class FunctionTypeRepr extends FunctionTypeReprBase { }
|
||||
@@ -0,0 +1,4 @@
|
||||
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
|
||||
private import codeql.swift.generated.typerepr.GenericIdentTypeRepr
|
||||
|
||||
class GenericIdentTypeRepr extends GenericIdentTypeReprBase { }
|
||||
@@ -0,0 +1,4 @@
|
||||
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
|
||||
private import codeql.swift.generated.typerepr.IdentTypeRepr
|
||||
|
||||
class IdentTypeRepr extends IdentTypeReprBase { }
|
||||
@@ -0,0 +1,4 @@
|
||||
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
|
||||
private import codeql.swift.generated.typerepr.ImplicitlyUnwrappedOptionalTypeRepr
|
||||
|
||||
class ImplicitlyUnwrappedOptionalTypeRepr extends ImplicitlyUnwrappedOptionalTypeReprBase { }
|
||||
@@ -0,0 +1,4 @@
|
||||
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
|
||||
private import codeql.swift.generated.typerepr.InOutTypeRepr
|
||||
|
||||
class InOutTypeRepr extends InOutTypeReprBase { }
|
||||
@@ -0,0 +1,4 @@
|
||||
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
|
||||
private import codeql.swift.generated.typerepr.IsolatedTypeRepr
|
||||
|
||||
class IsolatedTypeRepr extends IsolatedTypeReprBase { }
|
||||
@@ -0,0 +1,4 @@
|
||||
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
|
||||
private import codeql.swift.generated.typerepr.MetatypeTypeRepr
|
||||
|
||||
class MetatypeTypeRepr extends MetatypeTypeReprBase { }
|
||||
@@ -0,0 +1,4 @@
|
||||
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
|
||||
private import codeql.swift.generated.typerepr.NamedOpaqueReturnTypeRepr
|
||||
|
||||
class NamedOpaqueReturnTypeRepr extends NamedOpaqueReturnTypeReprBase { }
|
||||
@@ -0,0 +1,4 @@
|
||||
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
|
||||
private import codeql.swift.generated.typerepr.OpaqueReturnTypeRepr
|
||||
|
||||
class OpaqueReturnTypeRepr extends OpaqueReturnTypeReprBase { }
|
||||
@@ -0,0 +1,4 @@
|
||||
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
|
||||
private import codeql.swift.generated.typerepr.OptionalTypeRepr
|
||||
|
||||
class OptionalTypeRepr extends OptionalTypeReprBase { }
|
||||
@@ -0,0 +1,4 @@
|
||||
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
|
||||
private import codeql.swift.generated.typerepr.OwnedTypeRepr
|
||||
|
||||
class OwnedTypeRepr extends OwnedTypeReprBase { }
|
||||
@@ -0,0 +1,4 @@
|
||||
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
|
||||
private import codeql.swift.generated.typerepr.PlaceholderTypeRepr
|
||||
|
||||
class PlaceholderTypeRepr extends PlaceholderTypeReprBase { }
|
||||
@@ -0,0 +1,4 @@
|
||||
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
|
||||
private import codeql.swift.generated.typerepr.ProtocolTypeRepr
|
||||
|
||||
class ProtocolTypeRepr extends ProtocolTypeReprBase { }
|
||||
@@ -0,0 +1,4 @@
|
||||
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
|
||||
private import codeql.swift.generated.typerepr.SharedTypeRepr
|
||||
|
||||
class SharedTypeRepr extends SharedTypeReprBase { }
|
||||
@@ -0,0 +1,4 @@
|
||||
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
|
||||
private import codeql.swift.generated.typerepr.SilBoxTypeRepr
|
||||
|
||||
class SilBoxTypeRepr extends SilBoxTypeReprBase { }
|
||||
@@ -0,0 +1,4 @@
|
||||
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
|
||||
private import codeql.swift.generated.typerepr.SimpleIdentTypeRepr
|
||||
|
||||
class SimpleIdentTypeRepr extends SimpleIdentTypeReprBase { }
|
||||
@@ -0,0 +1,4 @@
|
||||
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
|
||||
private import codeql.swift.generated.typerepr.SpecifierTypeRepr
|
||||
|
||||
class SpecifierTypeRepr extends SpecifierTypeReprBase { }
|
||||
@@ -0,0 +1,4 @@
|
||||
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
|
||||
private import codeql.swift.generated.typerepr.TupleTypeRepr
|
||||
|
||||
class TupleTypeRepr extends TupleTypeReprBase { }
|
||||
@@ -13,4 +13,6 @@ class ElementBase extends @element {
|
||||
or
|
||||
result = getResolveStep().resolve()
|
||||
}
|
||||
|
||||
predicate isUnknown() { element_is_unknown(this) }
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.decl.Decl
|
||||
import codeql.swift.elements.expr.Expr
|
||||
import codeql.swift.elements.pattern.Pattern
|
||||
import codeql.swift.elements.stmt.Stmt
|
||||
import codeql.swift.elements.typerepr.TypeRepr
|
||||
|
||||
class UnknownAstNodeBase extends @unknown_ast_node, Decl, Expr, Pattern, Stmt, TypeRepr {
|
||||
override string getAPrimaryQlClass() { result = "UnknownAstNode" }
|
||||
|
||||
string getName() { unknown_ast_nodes(this, result) }
|
||||
}
|
||||
@@ -1,6 +1,16 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.decl.OperatorDecl
|
||||
import codeql.swift.elements.decl.PrecedenceGroupDecl
|
||||
|
||||
class InfixOperatorDeclBase extends @infix_operator_decl, OperatorDecl {
|
||||
override string getAPrimaryQlClass() { result = "InfixOperatorDecl" }
|
||||
|
||||
PrecedenceGroupDecl getPrecedenceGroup() {
|
||||
exists(PrecedenceGroupDecl x |
|
||||
infix_operator_decl_precedence_groups(this, x) and
|
||||
result = x.resolve()
|
||||
)
|
||||
}
|
||||
|
||||
predicate hasPrecedenceGroup() { exists(getPrecedenceGroup()) }
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.decl.Decl
|
||||
|
||||
class OperatorDeclBase extends @operator_decl, Decl { }
|
||||
class OperatorDeclBase extends @operator_decl, Decl {
|
||||
string getName() { operator_decls(this, result) }
|
||||
}
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.type.Type
|
||||
import codeql.swift.elements.decl.ValueDecl
|
||||
|
||||
class TypeDeclBase extends @type_decl, ValueDecl {
|
||||
string getName() { type_decls(this, result) }
|
||||
|
||||
Type getBaseType(int index) {
|
||||
exists(Type x |
|
||||
type_decl_base_types(this, index, x) and
|
||||
result = x.resolve()
|
||||
)
|
||||
}
|
||||
|
||||
Type getABaseType() { result = getBaseType(_) }
|
||||
|
||||
int getNumberOfBaseTypes() { result = count(getABaseType()) }
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.decl.AbstractStorageDecl
|
||||
import codeql.swift.elements.expr.Expr
|
||||
import codeql.swift.elements.pattern.Pattern
|
||||
import codeql.swift.elements.type.Type
|
||||
|
||||
class VarDeclBase extends @var_decl, AbstractStorageDecl {
|
||||
@@ -11,4 +13,31 @@ class VarDeclBase extends @var_decl, AbstractStorageDecl {
|
||||
result = x.resolve()
|
||||
)
|
||||
}
|
||||
|
||||
Type getAttachedPropertyWrapperType() {
|
||||
exists(Type x |
|
||||
var_decl_attached_property_wrapper_types(this, x) and
|
||||
result = x.resolve()
|
||||
)
|
||||
}
|
||||
|
||||
predicate hasAttachedPropertyWrapperType() { exists(getAttachedPropertyWrapperType()) }
|
||||
|
||||
Pattern getParentPattern() {
|
||||
exists(Pattern x |
|
||||
var_decl_parent_patterns(this, x) and
|
||||
result = x.resolve()
|
||||
)
|
||||
}
|
||||
|
||||
predicate hasParentPattern() { exists(getParentPattern()) }
|
||||
|
||||
Expr getParentInitializer() {
|
||||
exists(Expr x |
|
||||
var_decl_parent_initializers(this, x) and
|
||||
result = x.resolve()
|
||||
)
|
||||
}
|
||||
|
||||
predicate hasParentInitializer() { exists(getParentInitializer()) }
|
||||
}
|
||||
|
||||
@@ -2,20 +2,21 @@
|
||||
import codeql.swift.elements.stmt.BraceStmt
|
||||
import codeql.swift.elements.expr.Expr
|
||||
import codeql.swift.elements.stmt.LabeledStmt
|
||||
import codeql.swift.elements.pattern.Pattern
|
||||
|
||||
class ForEachStmtBase extends @for_each_stmt, LabeledStmt {
|
||||
override string getAPrimaryQlClass() { result = "ForEachStmt" }
|
||||
|
||||
BraceStmt getBody() {
|
||||
exists(BraceStmt x |
|
||||
for_each_stmts(this, x, _) and
|
||||
Pattern getPattern() {
|
||||
exists(Pattern x |
|
||||
for_each_stmts(this, x, _, _) and
|
||||
result = x.resolve()
|
||||
)
|
||||
}
|
||||
|
||||
Expr getSequence() {
|
||||
exists(Expr x |
|
||||
for_each_stmts(this, _, x) and
|
||||
for_each_stmts(this, _, x, _) and
|
||||
result = x.resolve()
|
||||
)
|
||||
}
|
||||
@@ -28,4 +29,11 @@ class ForEachStmtBase extends @for_each_stmt, LabeledStmt {
|
||||
}
|
||||
|
||||
predicate hasWhere() { exists(getWhere()) }
|
||||
|
||||
BraceStmt getBody() {
|
||||
exists(BraceStmt x |
|
||||
for_each_stmts(this, _, _, x) and
|
||||
result = x.resolve()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,16 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.type.NominalOrBoundGenericNominalType
|
||||
import codeql.swift.elements.type.Type
|
||||
|
||||
class BoundGenericTypeBase extends @bound_generic_type, NominalOrBoundGenericNominalType { }
|
||||
class BoundGenericTypeBase extends @bound_generic_type, NominalOrBoundGenericNominalType {
|
||||
Type getArgType(int index) {
|
||||
exists(Type x |
|
||||
bound_generic_type_arg_types(this, index, x) and
|
||||
result = x.resolve()
|
||||
)
|
||||
}
|
||||
|
||||
Type getAnArgType() { result = getArgType(_) }
|
||||
|
||||
int getNumberOfArgTypes() { result = count(getAnArgType()) }
|
||||
}
|
||||
|
||||
@@ -3,4 +3,8 @@ import codeql.swift.elements.type.AnyBuiltinIntegerType
|
||||
|
||||
class BuiltinIntegerTypeBase extends @builtin_integer_type, AnyBuiltinIntegerType {
|
||||
override string getAPrimaryQlClass() { result = "BuiltinIntegerType" }
|
||||
|
||||
int getWidth() { builtin_integer_type_widths(this, result) }
|
||||
|
||||
predicate hasWidth() { exists(getWidth()) }
|
||||
}
|
||||
|
||||
@@ -1,14 +1,6 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.decl.ClassDecl
|
||||
import codeql.swift.elements.type.NominalType
|
||||
|
||||
class ClassTypeBase extends @class_type, NominalType {
|
||||
override string getAPrimaryQlClass() { result = "ClassType" }
|
||||
|
||||
ClassDecl getDecl() {
|
||||
exists(ClassDecl x |
|
||||
class_types(this, x) and
|
||||
result = x.resolve()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,21 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.decl.AssociatedTypeDecl
|
||||
import codeql.swift.elements.type.Type
|
||||
|
||||
class DependentMemberTypeBase extends @dependent_member_type, Type {
|
||||
override string getAPrimaryQlClass() { result = "DependentMemberType" }
|
||||
|
||||
Type getBaseType() {
|
||||
exists(Type x |
|
||||
dependent_member_types(this, x, _) and
|
||||
result = x.resolve()
|
||||
)
|
||||
}
|
||||
|
||||
AssociatedTypeDecl getAssociatedTypeDecl() {
|
||||
exists(AssociatedTypeDecl x |
|
||||
dependent_member_types(this, _, x) and
|
||||
result = x.resolve()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,21 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.type.SyntaxSugarType
|
||||
import codeql.swift.elements.type.Type
|
||||
|
||||
class DictionaryTypeBase extends @dictionary_type, SyntaxSugarType {
|
||||
override string getAPrimaryQlClass() { result = "DictionaryType" }
|
||||
|
||||
Type getKeyType() {
|
||||
exists(Type x |
|
||||
dictionary_types(this, x, _) and
|
||||
result = x.resolve()
|
||||
)
|
||||
}
|
||||
|
||||
Type getValueType() {
|
||||
exists(Type x |
|
||||
dictionary_types(this, _, x) and
|
||||
result = x.resolve()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.type.SugarType
|
||||
import codeql.swift.elements.type.Type
|
||||
|
||||
class ParenTypeBase extends @paren_type, SugarType {
|
||||
override string getAPrimaryQlClass() { result = "ParenType" }
|
||||
|
||||
Type getType() {
|
||||
exists(Type x |
|
||||
paren_types(this, x) and
|
||||
result = x.resolve()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,6 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.type.NominalType
|
||||
import codeql.swift.elements.decl.StructDecl
|
||||
|
||||
class StructTypeBase extends @struct_type, NominalType {
|
||||
override string getAPrimaryQlClass() { result = "StructType" }
|
||||
|
||||
StructDecl getDecl() {
|
||||
exists(StructDecl x |
|
||||
struct_types(this, x) and
|
||||
result = x.resolve()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,4 +3,21 @@ import codeql.swift.elements.type.Type
|
||||
|
||||
class TupleTypeBase extends @tuple_type, Type {
|
||||
override string getAPrimaryQlClass() { result = "TupleType" }
|
||||
|
||||
Type getType(int index) {
|
||||
exists(Type x |
|
||||
tuple_type_types(this, index, x) and
|
||||
result = x.resolve()
|
||||
)
|
||||
}
|
||||
|
||||
Type getAType() { result = getType(_) }
|
||||
|
||||
int getNumberOfTypes() { result = count(getAType()) }
|
||||
|
||||
string getName(int index) { tuple_type_names(this, index, result) }
|
||||
|
||||
string getAName() { result = getName(_) }
|
||||
|
||||
int getNumberOfNames() { result = count(getAName()) }
|
||||
}
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.type.SugarType
|
||||
import codeql.swift.elements.decl.TypeAliasDecl
|
||||
|
||||
class TypeAliasTypeBase extends @type_alias_type, SugarType {
|
||||
override string getAPrimaryQlClass() { result = "TypeAliasType" }
|
||||
|
||||
TypeAliasDecl getDecl() {
|
||||
exists(TypeAliasDecl x |
|
||||
type_alias_types(this, x) and
|
||||
result = x.resolve()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.type.SyntaxSugarType
|
||||
import codeql.swift.elements.type.Type
|
||||
|
||||
class UnarySyntaxSugarTypeBase extends @unary_syntax_sugar_type, SyntaxSugarType { }
|
||||
class UnarySyntaxSugarTypeBase extends @unary_syntax_sugar_type, SyntaxSugarType {
|
||||
Type getBaseType() {
|
||||
exists(Type x |
|
||||
unary_syntax_sugar_types(this, x) and
|
||||
result = x.resolve()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.type.Type
|
||||
|
||||
class UnknownTypeBase extends @unknown_type, Type {
|
||||
override string getAPrimaryQlClass() { result = "UnknownType" }
|
||||
|
||||
string getName() { unknown_types(this, result) }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.typerepr.TypeRepr
|
||||
|
||||
class ArrayTypeReprBase extends @array_type_repr, TypeRepr {
|
||||
override string getAPrimaryQlClass() { result = "ArrayTypeRepr" }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.typerepr.TypeRepr
|
||||
|
||||
class AttributedTypeReprBase extends @attributed_type_repr, TypeRepr {
|
||||
override string getAPrimaryQlClass() { result = "AttributedTypeRepr" }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.typerepr.SpecifierTypeRepr
|
||||
|
||||
class CompileTimeConstTypeReprBase extends @compile_time_const_type_repr, SpecifierTypeRepr {
|
||||
override string getAPrimaryQlClass() { result = "CompileTimeConstTypeRepr" }
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.typerepr.IdentTypeRepr
|
||||
|
||||
class ComponentIdentTypeReprBase extends @component_ident_type_repr, IdentTypeRepr { }
|
||||
@@ -0,0 +1,6 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.typerepr.TypeRepr
|
||||
|
||||
class CompositionTypeReprBase extends @composition_type_repr, TypeRepr {
|
||||
override string getAPrimaryQlClass() { result = "CompositionTypeRepr" }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.typerepr.IdentTypeRepr
|
||||
|
||||
class CompoundIdentTypeReprBase extends @compound_ident_type_repr, IdentTypeRepr {
|
||||
override string getAPrimaryQlClass() { result = "CompoundIdentTypeRepr" }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.typerepr.TypeRepr
|
||||
|
||||
class DictionaryTypeReprBase extends @dictionary_type_repr, TypeRepr {
|
||||
override string getAPrimaryQlClass() { result = "DictionaryTypeRepr" }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.typerepr.TypeRepr
|
||||
|
||||
class ErrorTypeReprBase extends @error_type_repr, TypeRepr {
|
||||
override string getAPrimaryQlClass() { result = "ErrorTypeRepr" }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.typerepr.TypeRepr
|
||||
|
||||
class ExistentialTypeReprBase extends @existential_type_repr, TypeRepr {
|
||||
override string getAPrimaryQlClass() { result = "ExistentialTypeRepr" }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.typerepr.TypeRepr
|
||||
|
||||
class FixedTypeReprBase extends @fixed_type_repr, TypeRepr {
|
||||
override string getAPrimaryQlClass() { result = "FixedTypeRepr" }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.typerepr.TypeRepr
|
||||
|
||||
class FunctionTypeReprBase extends @function_type_repr, TypeRepr {
|
||||
override string getAPrimaryQlClass() { result = "FunctionTypeRepr" }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.typerepr.ComponentIdentTypeRepr
|
||||
|
||||
class GenericIdentTypeReprBase extends @generic_ident_type_repr, ComponentIdentTypeRepr {
|
||||
override string getAPrimaryQlClass() { result = "GenericIdentTypeRepr" }
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.typerepr.TypeRepr
|
||||
|
||||
class IdentTypeReprBase extends @ident_type_repr, TypeRepr { }
|
||||
@@ -0,0 +1,7 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.typerepr.TypeRepr
|
||||
|
||||
class ImplicitlyUnwrappedOptionalTypeReprBase extends @implicitly_unwrapped_optional_type_repr,
|
||||
TypeRepr {
|
||||
override string getAPrimaryQlClass() { result = "ImplicitlyUnwrappedOptionalTypeRepr" }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.typerepr.SpecifierTypeRepr
|
||||
|
||||
class InOutTypeReprBase extends @in_out_type_repr, SpecifierTypeRepr {
|
||||
override string getAPrimaryQlClass() { result = "InOutTypeRepr" }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.typerepr.SpecifierTypeRepr
|
||||
|
||||
class IsolatedTypeReprBase extends @isolated_type_repr, SpecifierTypeRepr {
|
||||
override string getAPrimaryQlClass() { result = "IsolatedTypeRepr" }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.typerepr.TypeRepr
|
||||
|
||||
class MetatypeTypeReprBase extends @metatype_type_repr, TypeRepr {
|
||||
override string getAPrimaryQlClass() { result = "MetatypeTypeRepr" }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.typerepr.TypeRepr
|
||||
|
||||
class NamedOpaqueReturnTypeReprBase extends @named_opaque_return_type_repr, TypeRepr {
|
||||
override string getAPrimaryQlClass() { result = "NamedOpaqueReturnTypeRepr" }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.typerepr.TypeRepr
|
||||
|
||||
class OpaqueReturnTypeReprBase extends @opaque_return_type_repr, TypeRepr {
|
||||
override string getAPrimaryQlClass() { result = "OpaqueReturnTypeRepr" }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.typerepr.TypeRepr
|
||||
|
||||
class OptionalTypeReprBase extends @optional_type_repr, TypeRepr {
|
||||
override string getAPrimaryQlClass() { result = "OptionalTypeRepr" }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.typerepr.SpecifierTypeRepr
|
||||
|
||||
class OwnedTypeReprBase extends @owned_type_repr, SpecifierTypeRepr {
|
||||
override string getAPrimaryQlClass() { result = "OwnedTypeRepr" }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.typerepr.TypeRepr
|
||||
|
||||
class PlaceholderTypeReprBase extends @placeholder_type_repr, TypeRepr {
|
||||
override string getAPrimaryQlClass() { result = "PlaceholderTypeRepr" }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.typerepr.TypeRepr
|
||||
|
||||
class ProtocolTypeReprBase extends @protocol_type_repr, TypeRepr {
|
||||
override string getAPrimaryQlClass() { result = "ProtocolTypeRepr" }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.typerepr.SpecifierTypeRepr
|
||||
|
||||
class SharedTypeReprBase extends @shared_type_repr, SpecifierTypeRepr {
|
||||
override string getAPrimaryQlClass() { result = "SharedTypeRepr" }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.typerepr.TypeRepr
|
||||
|
||||
class SilBoxTypeReprBase extends @sil_box_type_repr, TypeRepr {
|
||||
override string getAPrimaryQlClass() { result = "SilBoxTypeRepr" }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.typerepr.ComponentIdentTypeRepr
|
||||
|
||||
class SimpleIdentTypeReprBase extends @simple_ident_type_repr, ComponentIdentTypeRepr {
|
||||
override string getAPrimaryQlClass() { result = "SimpleIdentTypeRepr" }
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.typerepr.TypeRepr
|
||||
|
||||
class SpecifierTypeReprBase extends @specifier_type_repr, TypeRepr { }
|
||||
@@ -0,0 +1,6 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.typerepr.TypeRepr
|
||||
|
||||
class TupleTypeReprBase extends @tuple_type_repr, TypeRepr {
|
||||
override string getAPrimaryQlClass() { result = "TupleTypeRepr" }
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user