mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Swift: reorganize code
Visitor code has been split between header and sources to speed up incremental build. Moreover the code was reorganized using a new `infra` bazel package (and `visitors` got promoted to a bazel package as well).
This commit is contained in:
@@ -3,24 +3,15 @@ load("//swift:rules.bzl", "swift_cc_binary")
|
||||
swift_cc_binary(
|
||||
name = "extractor",
|
||||
srcs = [
|
||||
"SwiftDispatcher.h",
|
||||
"SwiftExtractor.cpp",
|
||||
"SwiftExtractor.h",
|
||||
"SwiftExtractorConfiguration.h",
|
||||
"SwiftTagTraits.h",
|
||||
"SwiftVisitor.h",
|
||||
"main.cpp",
|
||||
"visitors/DeclVisitor.h",
|
||||
"visitors/ExprVisitor.h",
|
||||
"visitors/PatternVisitor.h",
|
||||
"visitors/StmtVisitor.h",
|
||||
"visitors/TypeReprVisitor.h",
|
||||
"visitors/TypeVisitor.h",
|
||||
"visitors/VisitorBase.h",
|
||||
],
|
||||
visibility = ["//swift:__pkg__"],
|
||||
deps = [
|
||||
"//swift/extractor/trap",
|
||||
"//swift/extractor/infra",
|
||||
"//swift/extractor/visitors",
|
||||
"//swift/tools/prebuilt:swift-llvm-support",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
#include "swift/extractor/trap/generated/TrapClasses.h"
|
||||
#include "swift/extractor/trap/TrapOutput.h"
|
||||
#include "swift/extractor/SwiftVisitor.h"
|
||||
#include "swift/extractor/visitors/SwiftVisitor.h"
|
||||
|
||||
using namespace codeql;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "SwiftExtractorConfiguration.h"
|
||||
#include "swift/extractor/SwiftExtractorConfiguration.h"
|
||||
#include <swift/AST/SourceFile.h>
|
||||
#include <swift/Frontend/Frontend.h>
|
||||
#include <memory>
|
||||
|
||||
10
swift/extractor/infra/BUILD.bazel
Normal file
10
swift/extractor/infra/BUILD.bazel
Normal file
@@ -0,0 +1,10 @@
|
||||
load("//swift:rules.bzl", "swift_cc_library")
|
||||
|
||||
swift_cc_library(
|
||||
name = "infra",
|
||||
hdrs = glob(["*.h"]),
|
||||
visibility = ["//swift:__subpackages__"],
|
||||
deps = [
|
||||
"//swift/extractor/trap",
|
||||
],
|
||||
)
|
||||
@@ -2,11 +2,12 @@
|
||||
|
||||
#include "swift/extractor/trap/TrapArena.h"
|
||||
#include "swift/extractor/trap/TrapLabelStore.h"
|
||||
#include "swift/extractor/trap/TrapOutput.h"
|
||||
#include "swift/extractor/trap/generated/TrapClasses.h"
|
||||
#include "swift/extractor/SwiftTagTraits.h"
|
||||
#include <swift/AST/SourceFile.h>
|
||||
#include <swift/Basic/SourceManager.h>
|
||||
#include <llvm/Support/FileSystem.h>
|
||||
#include "swift/extractor/infra/SwiftTagTraits.h"
|
||||
#include "external/swift_prebuilt_linux/_virtual_includes/swift-llvm-support/swift/AST/SourceFile.h"
|
||||
#include "external/swift_prebuilt_linux/_virtual_includes/swift-llvm-support/swift/Basic/SourceManager.h"
|
||||
#include "external/swift_prebuilt_linux/_virtual_includes/swift-llvm-support/llvm/Support/FileSystem.h"
|
||||
|
||||
namespace codeql {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
// This file implements the mapping needed by the API defined in the TrapTagTraits.h, so that
|
||||
// TrapTagOf/TrapLabelOf provide the tags/labels for specific swift entity types.
|
||||
#include <swift/AST/ASTVisitor.h>
|
||||
#include "external/swift_prebuilt_linux/_virtual_includes/swift-llvm-support/swift/AST/ASTVisitor.h"
|
||||
#include "swift/extractor/trap/TrapTagTraits.h"
|
||||
#include "swift/extractor/trap/generated/TrapTags.h"
|
||||
|
||||
@@ -39,32 +39,32 @@ 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"
|
||||
#include "external/swift_prebuilt_linux/_virtual_includes/swift-llvm-support/swift/AST/StmtNodes.def"
|
||||
|
||||
MAP_TAG(Expr);
|
||||
#define ABSTRACT_EXPR(CLASS, PARENT) MAP_SUBTAG(CLASS##Expr, PARENT)
|
||||
#define EXPR(CLASS, PARENT) ABSTRACT_EXPR(CLASS, PARENT)
|
||||
#include "swift/AST/ExprNodes.def"
|
||||
#include "external/swift_prebuilt_linux/_virtual_includes/swift-llvm-support/swift/AST/ExprNodes.def"
|
||||
|
||||
MAP_TAG(Decl);
|
||||
#define ABSTRACT_DECL(CLASS, PARENT) MAP_SUBTAG(CLASS##Decl, PARENT)
|
||||
#define DECL(CLASS, PARENT) ABSTRACT_DECL(CLASS, PARENT)
|
||||
#include "swift/AST/DeclNodes.def"
|
||||
#include "external/swift_prebuilt_linux/_virtual_includes/swift-llvm-support/swift/AST/DeclNodes.def"
|
||||
|
||||
MAP_TAG(Pattern);
|
||||
#define ABSTRACT_PATTERN(CLASS, PARENT) MAP_SUBTAG(CLASS##Pattern, PARENT)
|
||||
#define PATTERN(CLASS, PARENT) ABSTRACT_PATTERN(CLASS, PARENT)
|
||||
#include "swift/AST/PatternNodes.def"
|
||||
#include "external/swift_prebuilt_linux/_virtual_includes/swift-llvm-support/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"
|
||||
#include "external/swift_prebuilt_linux/_virtual_includes/swift-llvm-support/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)
|
||||
#include "swift/AST/TypeNodes.def"
|
||||
#include "external/swift_prebuilt_linux/_virtual_includes/swift-llvm-support/swift/AST/TypeNodes.def"
|
||||
|
||||
OVERRIDE_TAG(FuncDecl, ConcreteFuncDeclTag);
|
||||
OVERRIDE_TAG(VarDecl, ConcreteVarDeclTag);
|
||||
@@ -1,3 +1,5 @@
|
||||
load("//swift:rules.bzl", "swift_cc_library")
|
||||
|
||||
genrule(
|
||||
name = "cppgen",
|
||||
srcs = [
|
||||
@@ -26,7 +28,7 @@ filegroup(
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
swift_cc_library(
|
||||
name = "trap",
|
||||
hdrs = glob(["*.h"]) + [
|
||||
"generated/TrapEntries.h",
|
||||
|
||||
12
swift/extractor/visitors/BUILD.bazel
Normal file
12
swift/extractor/visitors/BUILD.bazel
Normal file
@@ -0,0 +1,12 @@
|
||||
load("//swift:rules.bzl", "swift_cc_library")
|
||||
|
||||
swift_cc_library(
|
||||
name = "visitors",
|
||||
srcs = glob(["*.cpp"]),
|
||||
hdrs = glob(["*.h"]),
|
||||
visibility = ["//swift:__subpackages__"],
|
||||
deps = [
|
||||
"//swift/extractor/infra",
|
||||
"//swift/tools/prebuilt:swift-llvm-support",
|
||||
],
|
||||
)
|
||||
337
swift/extractor/visitors/DeclVisitor.cpp
Normal file
337
swift/extractor/visitors/DeclVisitor.cpp
Normal file
@@ -0,0 +1,337 @@
|
||||
#include "swift/extractor/visitors/DeclVisitor.h"
|
||||
|
||||
#include <swift/AST/GenericParamList.h>
|
||||
#include <swift/AST/ParameterList.h>
|
||||
|
||||
namespace codeql {
|
||||
namespace {
|
||||
// Constructs a `std::string` of the form `f(x:y:)` for a declaration
|
||||
// like `func f(x first: Int, y second: Int) { }`
|
||||
std::string constructName(const swift::DeclName& declName) {
|
||||
std::string name = declName.getBaseName().userFacingName().str();
|
||||
name += "(";
|
||||
for (const auto& argName : declName.getArgumentNames()) {
|
||||
if (argName.empty()) {
|
||||
name += "_:";
|
||||
} else {
|
||||
name += argName.str().str() + ":";
|
||||
}
|
||||
}
|
||||
name += ")";
|
||||
return name;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
std::variant<codeql::ConcreteFuncDecl, codeql::ConcreteFuncDeclsTrap>
|
||||
DeclVisitor::translateFuncDecl(const swift::FuncDecl& decl) {
|
||||
auto id = dispatcher_.assignNewLabel(decl, mangledName(decl));
|
||||
if (!dispatcher_.shouldEmitDeclBody(decl)) {
|
||||
return ConcreteFuncDeclsTrap{id};
|
||||
}
|
||||
ConcreteFuncDecl entry{id};
|
||||
fillAbstractFunctionDecl(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
std::variant<codeql::ConstructorDecl, codeql::ConstructorDeclsTrap>
|
||||
DeclVisitor::translateConstructorDecl(const swift::ConstructorDecl& decl) {
|
||||
auto id = dispatcher_.assignNewLabel(decl, mangledName(decl));
|
||||
if (!dispatcher_.shouldEmitDeclBody(decl)) {
|
||||
return ConstructorDeclsTrap{id};
|
||||
}
|
||||
ConstructorDecl entry{id};
|
||||
fillAbstractFunctionDecl(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
std::variant<codeql::DestructorDecl, codeql::DestructorDeclsTrap>
|
||||
DeclVisitor::translateDestructorDecl(const swift::DestructorDecl& decl) {
|
||||
auto id = dispatcher_.assignNewLabel(decl, mangledName(decl));
|
||||
if (!dispatcher_.shouldEmitDeclBody(decl)) {
|
||||
return DestructorDeclsTrap{id};
|
||||
}
|
||||
DestructorDecl entry{id};
|
||||
fillAbstractFunctionDecl(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::PrefixOperatorDecl DeclVisitor::translatePrefixOperatorDecl(
|
||||
const swift::PrefixOperatorDecl& decl) {
|
||||
PrefixOperatorDecl entry{dispatcher_.assignNewLabel(decl)};
|
||||
fillOperatorDecl(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::PostfixOperatorDecl DeclVisitor::translatePostfixOperatorDecl(
|
||||
const swift::PostfixOperatorDecl& decl) {
|
||||
PostfixOperatorDecl entry{dispatcher_.assignNewLabel(decl)};
|
||||
fillOperatorDecl(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::InfixOperatorDecl DeclVisitor::translateInfixOperatorDecl(
|
||||
const swift::InfixOperatorDecl& decl) {
|
||||
InfixOperatorDecl entry{dispatcher_.assignNewLabel(decl)};
|
||||
entry.precedence_group = dispatcher_.fetchOptionalLabel(decl.getPrecedenceGroup());
|
||||
fillOperatorDecl(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::PrecedenceGroupDecl DeclVisitor::translatePrecedenceGroupDecl(
|
||||
const swift::PrecedenceGroupDecl& decl) {
|
||||
PrecedenceGroupDecl entry{dispatcher_.assignNewLabel(decl)};
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::ParamDecl DeclVisitor::translateParamDecl(const swift::ParamDecl& decl) {
|
||||
// TODO: deduplicate
|
||||
ParamDecl entry{dispatcher_.assignNewLabel(decl)};
|
||||
fillVarDecl(decl, entry);
|
||||
entry.is_inout = decl.isInOut();
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::TopLevelCodeDecl DeclVisitor::translateTopLevelCodeDecl(
|
||||
const swift::TopLevelCodeDecl& decl) {
|
||||
TopLevelCodeDecl entry{dispatcher_.assignNewLabel(decl)};
|
||||
assert(decl.getBody() && "Expect top level code to have body");
|
||||
entry.body = dispatcher_.fetchLabel(decl.getBody());
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::PatternBindingDecl DeclVisitor::translatePatternBindingDecl(
|
||||
const swift::PatternBindingDecl& decl) {
|
||||
PatternBindingDecl entry{dispatcher_.assignNewLabel(decl)};
|
||||
for (unsigned i = 0; i < decl.getNumPatternEntries(); ++i) {
|
||||
auto pattern = decl.getPattern(i);
|
||||
assert(pattern && "Expect pattern binding decl to have all patterns");
|
||||
entry.patterns.push_back(dispatcher_.fetchLabel(pattern));
|
||||
entry.inits.push_back(dispatcher_.fetchOptionalLabel(decl.getInit(i)));
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::ConcreteVarDecl DeclVisitor::translateVarDecl(const swift::VarDecl& decl) {
|
||||
// TODO: deduplicate all non-local variables
|
||||
ConcreteVarDecl entry{dispatcher_.assignNewLabel(decl)};
|
||||
entry.introducer_int = static_cast<uint8_t>(decl.getIntroducer());
|
||||
fillVarDecl(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
std::variant<codeql::StructDecl, codeql::StructDeclsTrap> DeclVisitor::translateStructDecl(
|
||||
const swift::StructDecl& decl) {
|
||||
auto id = dispatcher_.assignNewLabel(decl, mangledName(decl));
|
||||
if (!dispatcher_.shouldEmitDeclBody(decl)) {
|
||||
return StructDeclsTrap{id};
|
||||
}
|
||||
StructDecl entry{id};
|
||||
fillNominalTypeDecl(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
std::variant<codeql::ClassDecl, codeql::ClassDeclsTrap> DeclVisitor::translateClassDecl(
|
||||
const swift::ClassDecl& decl) {
|
||||
auto id = dispatcher_.assignNewLabel(decl, mangledName(decl));
|
||||
if (!dispatcher_.shouldEmitDeclBody(decl)) {
|
||||
return ClassDeclsTrap{id};
|
||||
}
|
||||
ClassDecl entry{id};
|
||||
fillNominalTypeDecl(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
std::variant<codeql::EnumDecl, codeql::EnumDeclsTrap> DeclVisitor::translateEnumDecl(
|
||||
const swift::EnumDecl& decl) {
|
||||
auto id = dispatcher_.assignNewLabel(decl, mangledName(decl));
|
||||
if (!dispatcher_.shouldEmitDeclBody(decl)) {
|
||||
return EnumDeclsTrap{id};
|
||||
}
|
||||
EnumDecl entry{id};
|
||||
fillNominalTypeDecl(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
std::variant<codeql::ProtocolDecl, codeql::ProtocolDeclsTrap> DeclVisitor::translateProtocolDecl(
|
||||
const swift::ProtocolDecl& decl) {
|
||||
auto id = dispatcher_.assignNewLabel(decl, mangledName(decl));
|
||||
if (!dispatcher_.shouldEmitDeclBody(decl)) {
|
||||
return ProtocolDeclsTrap{id};
|
||||
}
|
||||
ProtocolDecl entry{id};
|
||||
fillNominalTypeDecl(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::EnumCaseDecl DeclVisitor::translateEnumCaseDecl(const swift::EnumCaseDecl& decl) {
|
||||
EnumCaseDecl entry{dispatcher_.assignNewLabel(decl)};
|
||||
entry.elements = dispatcher_.fetchRepeatedLabels(decl.getElements());
|
||||
return entry;
|
||||
}
|
||||
|
||||
std::variant<codeql::EnumElementDecl, codeql::EnumElementDeclsTrap>
|
||||
DeclVisitor::translateEnumElementDecl(const swift::EnumElementDecl& decl) {
|
||||
auto id = dispatcher_.assignNewLabel(decl, mangledName(decl));
|
||||
if (!dispatcher_.shouldEmitDeclBody(decl)) {
|
||||
return EnumElementDeclsTrap{id, decl.getNameStr().str()};
|
||||
}
|
||||
EnumElementDecl entry{id};
|
||||
entry.name = decl.getNameStr().str();
|
||||
if (decl.hasParameterList()) {
|
||||
entry.params = dispatcher_.fetchRepeatedLabels(*decl.getParameterList());
|
||||
}
|
||||
fillValueDecl(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::GenericTypeParamDecl DeclVisitor::translateGenericTypeParamDecl(
|
||||
const swift::GenericTypeParamDecl& decl) {
|
||||
// TODO: deduplicate
|
||||
GenericTypeParamDecl entry{dispatcher_.assignNewLabel(decl)};
|
||||
fillTypeDecl(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
std::variant<codeql::AssociatedTypeDecl, codeql::AssociatedTypeDeclsTrap>
|
||||
DeclVisitor::translateAssociatedTypeDecl(const swift::AssociatedTypeDecl& decl) {
|
||||
auto id = dispatcher_.assignNewLabel(decl, mangledName(decl));
|
||||
if (!dispatcher_.shouldEmitDeclBody(decl)) {
|
||||
return AssociatedTypeDeclsTrap{id};
|
||||
}
|
||||
AssociatedTypeDecl entry{id};
|
||||
fillTypeDecl(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
std::variant<codeql::TypeAliasDecl, codeql::TypeAliasDeclsTrap> DeclVisitor::translateTypeAliasDecl(
|
||||
const swift::TypeAliasDecl& decl) {
|
||||
auto id = dispatcher_.assignNewLabel(decl, mangledName(decl));
|
||||
if (!dispatcher_.shouldEmitDeclBody(decl)) {
|
||||
return TypeAliasDeclsTrap{id};
|
||||
}
|
||||
TypeAliasDecl entry{id};
|
||||
fillTypeDecl(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
std::variant<codeql::AccessorDecl, codeql::AccessorDeclsTrap> DeclVisitor::translateAccessorDecl(
|
||||
const swift::AccessorDecl& decl) {
|
||||
auto id = dispatcher_.assignNewLabel(decl, mangledName(decl));
|
||||
if (!dispatcher_.shouldEmitDeclBody(decl)) {
|
||||
return AccessorDeclsTrap{id};
|
||||
}
|
||||
AccessorDecl entry{id};
|
||||
switch (decl.getAccessorKind()) {
|
||||
case swift::AccessorKind::Get:
|
||||
entry.is_getter = true;
|
||||
break;
|
||||
case swift::AccessorKind::Set:
|
||||
entry.is_setter = true;
|
||||
break;
|
||||
case swift::AccessorKind::WillSet:
|
||||
entry.is_will_set = true;
|
||||
break;
|
||||
case swift::AccessorKind::DidSet:
|
||||
entry.is_did_set = true;
|
||||
break;
|
||||
}
|
||||
fillAbstractFunctionDecl(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
std::optional<codeql::SubscriptDecl> DeclVisitor::translateSubscriptDecl(
|
||||
const swift::SubscriptDecl& decl) {
|
||||
auto id = dispatcher_.assignNewLabel(decl, mangledName(decl));
|
||||
if (!dispatcher_.shouldEmitDeclBody(decl)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
SubscriptDecl entry{id};
|
||||
entry.element_type = dispatcher_.fetchLabel(decl.getElementInterfaceType());
|
||||
if (auto indices = decl.getIndices()) {
|
||||
entry.params = dispatcher_.fetchRepeatedLabels(*indices);
|
||||
}
|
||||
fillAbstractStorageDecl(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::ExtensionDecl DeclVisitor::translateExtensionDecl(const swift::ExtensionDecl& decl) {
|
||||
ExtensionDecl entry{dispatcher_.assignNewLabel(decl)};
|
||||
entry.extended_type_decl = dispatcher_.fetchLabel(decl.getExtendedNominal());
|
||||
fillGenericContext(decl, entry);
|
||||
fillIterableDeclContext(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
std::string DeclVisitor::mangledName(const swift::ValueDecl& decl) {
|
||||
// prefix adds a couple of special symbols, we don't necessary need them
|
||||
return mangler.mangleAnyDecl(&decl, /* prefix = */ false);
|
||||
}
|
||||
|
||||
void DeclVisitor::fillAbstractFunctionDecl(const swift::AbstractFunctionDecl& decl,
|
||||
codeql::AbstractFunctionDecl& entry) {
|
||||
assert(decl.hasParameterList() && "Expect functions to have a parameter list");
|
||||
entry.name = !decl.hasName() ? "(unnamed function decl)" : constructName(decl.getName());
|
||||
entry.body = dispatcher_.fetchOptionalLabel(decl.getBody());
|
||||
entry.params = dispatcher_.fetchRepeatedLabels(*decl.getParameters());
|
||||
fillValueDecl(decl, entry);
|
||||
fillGenericContext(decl, entry);
|
||||
}
|
||||
|
||||
void DeclVisitor::fillOperatorDecl(const swift::OperatorDecl& decl, codeql::OperatorDecl& entry) {
|
||||
entry.name = decl.getName().str().str();
|
||||
}
|
||||
|
||||
void DeclVisitor::fillTypeDecl(const swift::TypeDecl& decl, codeql::TypeDecl& entry) {
|
||||
entry.name = decl.getNameStr().str();
|
||||
for (auto& typeLoc : decl.getInherited()) {
|
||||
if (auto type = typeLoc.getType()) {
|
||||
entry.base_types.push_back(dispatcher_.fetchLabel(type));
|
||||
}
|
||||
}
|
||||
fillValueDecl(decl, entry);
|
||||
}
|
||||
|
||||
void DeclVisitor::fillIterableDeclContext(const swift::IterableDeclContext& decl,
|
||||
codeql::IterableDeclContext& entry) {
|
||||
entry.members = dispatcher_.fetchRepeatedLabels(decl.getAllMembers());
|
||||
}
|
||||
|
||||
void DeclVisitor::fillVarDecl(const swift::VarDecl& decl, codeql::VarDecl& entry) {
|
||||
entry.name = decl.getNameStr().str();
|
||||
entry.type = dispatcher_.fetchLabel(decl.getType());
|
||||
entry.parent_pattern = dispatcher_.fetchOptionalLabel(decl.getParentPattern());
|
||||
entry.parent_initializer = dispatcher_.fetchOptionalLabel(decl.getParentInitializer());
|
||||
if (decl.hasAttachedPropertyWrapper()) {
|
||||
entry.attached_property_wrapper_type =
|
||||
dispatcher_.fetchOptionalLabel(decl.getPropertyWrapperBackingPropertyType());
|
||||
}
|
||||
fillAbstractStorageDecl(decl, entry);
|
||||
}
|
||||
|
||||
void DeclVisitor::fillNominalTypeDecl(const swift::NominalTypeDecl& decl,
|
||||
codeql::NominalTypeDecl& entry) {
|
||||
entry.type = dispatcher_.fetchLabel(decl.getDeclaredType());
|
||||
fillGenericContext(decl, entry);
|
||||
fillIterableDeclContext(decl, entry);
|
||||
fillTypeDecl(decl, entry);
|
||||
}
|
||||
|
||||
void DeclVisitor::fillGenericContext(const swift::GenericContext& decl,
|
||||
codeql::GenericContext& entry) {
|
||||
if (auto params = decl.getGenericParams()) {
|
||||
entry.generic_type_params = dispatcher_.fetchRepeatedLabels(*params);
|
||||
}
|
||||
}
|
||||
|
||||
void DeclVisitor::fillValueDecl(const swift::ValueDecl& decl, codeql::ValueDecl& entry) {
|
||||
assert(decl.getInterfaceType() && "Expect ValueDecl to have InterfaceType");
|
||||
entry.interface_type = dispatcher_.fetchLabel(decl.getInterfaceType());
|
||||
}
|
||||
|
||||
void DeclVisitor::fillAbstractStorageDecl(const swift::AbstractStorageDecl& decl,
|
||||
codeql::AbstractStorageDecl& entry) {
|
||||
entry.accessor_decls = dispatcher_.fetchRepeatedLabels(decl.getAllAccessors());
|
||||
fillValueDecl(decl, entry);
|
||||
}
|
||||
|
||||
} // namespace codeql
|
||||
@@ -1,8 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <swift/AST/Decl.h>
|
||||
#include <swift/AST/GenericParamList.h>
|
||||
#include <swift/AST/ParameterList.h>
|
||||
#include <swift/AST/ASTMangler.h>
|
||||
|
||||
#include "swift/extractor/visitors/VisitorBase.h"
|
||||
@@ -17,324 +15,55 @@ class DeclVisitor : public AstVisitorBase<DeclVisitor> {
|
||||
using AstVisitorBase<DeclVisitor>::AstVisitorBase;
|
||||
|
||||
std::variant<codeql::ConcreteFuncDecl, codeql::ConcreteFuncDeclsTrap> translateFuncDecl(
|
||||
const swift::FuncDecl& decl) {
|
||||
auto id = dispatcher_.assignNewLabel(decl, mangledName(decl));
|
||||
if (!dispatcher_.shouldEmitDeclBody(decl)) {
|
||||
return ConcreteFuncDeclsTrap{id};
|
||||
}
|
||||
ConcreteFuncDecl entry{id};
|
||||
fillAbstractFunctionDecl(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
const swift::FuncDecl& decl);
|
||||
std::variant<codeql::ConstructorDecl, codeql::ConstructorDeclsTrap> translateConstructorDecl(
|
||||
const swift::ConstructorDecl& decl) {
|
||||
auto id = dispatcher_.assignNewLabel(decl, mangledName(decl));
|
||||
if (!dispatcher_.shouldEmitDeclBody(decl)) {
|
||||
return ConstructorDeclsTrap{id};
|
||||
}
|
||||
ConstructorDecl entry{id};
|
||||
fillAbstractFunctionDecl(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
const swift::ConstructorDecl& decl);
|
||||
std::variant<codeql::DestructorDecl, codeql::DestructorDeclsTrap> translateDestructorDecl(
|
||||
const swift::DestructorDecl& decl) {
|
||||
auto id = dispatcher_.assignNewLabel(decl, mangledName(decl));
|
||||
if (!dispatcher_.shouldEmitDeclBody(decl)) {
|
||||
return DestructorDeclsTrap{id};
|
||||
}
|
||||
DestructorDecl entry{id};
|
||||
fillAbstractFunctionDecl(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::PrefixOperatorDecl translatePrefixOperatorDecl(const swift::PrefixOperatorDecl& decl) {
|
||||
PrefixOperatorDecl entry{dispatcher_.assignNewLabel(decl)};
|
||||
fillOperatorDecl(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::PostfixOperatorDecl translatePostfixOperatorDecl(const swift::PostfixOperatorDecl& decl) {
|
||||
PostfixOperatorDecl entry{dispatcher_.assignNewLabel(decl)};
|
||||
fillOperatorDecl(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::InfixOperatorDecl translateInfixOperatorDecl(const swift::InfixOperatorDecl& decl) {
|
||||
InfixOperatorDecl entry{dispatcher_.assignNewLabel(decl)};
|
||||
entry.precedence_group = dispatcher_.fetchOptionalLabel(decl.getPrecedenceGroup());
|
||||
fillOperatorDecl(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::PrecedenceGroupDecl translatePrecedenceGroupDecl(const swift::PrecedenceGroupDecl& decl) {
|
||||
PrecedenceGroupDecl entry{dispatcher_.assignNewLabel(decl)};
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::ParamDecl translateParamDecl(const swift::ParamDecl& decl) {
|
||||
// TODO: deduplicate
|
||||
ParamDecl entry{dispatcher_.assignNewLabel(decl)};
|
||||
fillVarDecl(decl, entry);
|
||||
entry.is_inout = decl.isInOut();
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::TopLevelCodeDecl translateTopLevelCodeDecl(const swift::TopLevelCodeDecl& decl) {
|
||||
TopLevelCodeDecl entry{dispatcher_.assignNewLabel(decl)};
|
||||
assert(decl.getBody() && "Expect top level code to have body");
|
||||
entry.body = dispatcher_.fetchLabel(decl.getBody());
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::PatternBindingDecl translatePatternBindingDecl(const swift::PatternBindingDecl& decl) {
|
||||
PatternBindingDecl entry{dispatcher_.assignNewLabel(decl)};
|
||||
for (unsigned i = 0; i < decl.getNumPatternEntries(); ++i) {
|
||||
auto pattern = decl.getPattern(i);
|
||||
assert(pattern && "Expect pattern binding decl to have all patterns");
|
||||
entry.patterns.push_back(dispatcher_.fetchLabel(pattern));
|
||||
entry.inits.push_back(dispatcher_.fetchOptionalLabel(decl.getInit(i)));
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::ConcreteVarDecl translateVarDecl(const swift::VarDecl& decl) {
|
||||
// TODO: deduplicate all non-local variables
|
||||
ConcreteVarDecl entry{dispatcher_.assignNewLabel(decl)};
|
||||
entry.introducer_int = static_cast<uint8_t>(decl.getIntroducer());
|
||||
fillVarDecl(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
const swift::DestructorDecl& decl);
|
||||
codeql::PrefixOperatorDecl translatePrefixOperatorDecl(const swift::PrefixOperatorDecl& decl);
|
||||
codeql::PostfixOperatorDecl translatePostfixOperatorDecl(const swift::PostfixOperatorDecl& decl);
|
||||
codeql::InfixOperatorDecl translateInfixOperatorDecl(const swift::InfixOperatorDecl& decl);
|
||||
codeql::PrecedenceGroupDecl translatePrecedenceGroupDecl(const swift::PrecedenceGroupDecl& decl);
|
||||
codeql::ParamDecl translateParamDecl(const swift::ParamDecl& decl);
|
||||
codeql::TopLevelCodeDecl translateTopLevelCodeDecl(const swift::TopLevelCodeDecl& decl);
|
||||
codeql::PatternBindingDecl translatePatternBindingDecl(const swift::PatternBindingDecl& decl);
|
||||
codeql::ConcreteVarDecl translateVarDecl(const swift::VarDecl& decl);
|
||||
std::variant<codeql::StructDecl, codeql::StructDeclsTrap> translateStructDecl(
|
||||
const swift::StructDecl& decl) {
|
||||
auto id = dispatcher_.assignNewLabel(decl, mangledName(decl));
|
||||
if (!dispatcher_.shouldEmitDeclBody(decl)) {
|
||||
return StructDeclsTrap{id};
|
||||
}
|
||||
StructDecl entry{id};
|
||||
fillNominalTypeDecl(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
const swift::StructDecl& decl);
|
||||
std::variant<codeql::ClassDecl, codeql::ClassDeclsTrap> translateClassDecl(
|
||||
const swift::ClassDecl& decl) {
|
||||
auto id = dispatcher_.assignNewLabel(decl, mangledName(decl));
|
||||
if (!dispatcher_.shouldEmitDeclBody(decl)) {
|
||||
return ClassDeclsTrap{id};
|
||||
}
|
||||
ClassDecl entry{id};
|
||||
fillNominalTypeDecl(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
const swift::ClassDecl& decl);
|
||||
std::variant<codeql::EnumDecl, codeql::EnumDeclsTrap> translateEnumDecl(
|
||||
const swift::EnumDecl& decl) {
|
||||
auto id = dispatcher_.assignNewLabel(decl, mangledName(decl));
|
||||
if (!dispatcher_.shouldEmitDeclBody(decl)) {
|
||||
return EnumDeclsTrap{id};
|
||||
}
|
||||
EnumDecl entry{id};
|
||||
fillNominalTypeDecl(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
const swift::EnumDecl& decl);
|
||||
std::variant<codeql::ProtocolDecl, codeql::ProtocolDeclsTrap> translateProtocolDecl(
|
||||
const swift::ProtocolDecl& decl) {
|
||||
auto id = dispatcher_.assignNewLabel(decl, mangledName(decl));
|
||||
if (!dispatcher_.shouldEmitDeclBody(decl)) {
|
||||
return ProtocolDeclsTrap{id};
|
||||
}
|
||||
ProtocolDecl entry{id};
|
||||
fillNominalTypeDecl(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::EnumCaseDecl translateEnumCaseDecl(const swift::EnumCaseDecl& decl) {
|
||||
EnumCaseDecl entry{dispatcher_.assignNewLabel(decl)};
|
||||
entry.elements = dispatcher_.fetchRepeatedLabels(decl.getElements());
|
||||
return entry;
|
||||
}
|
||||
|
||||
const swift::ProtocolDecl& decl);
|
||||
codeql::EnumCaseDecl translateEnumCaseDecl(const swift::EnumCaseDecl& decl);
|
||||
std::variant<codeql::EnumElementDecl, codeql::EnumElementDeclsTrap> translateEnumElementDecl(
|
||||
const swift::EnumElementDecl& decl) {
|
||||
auto id = dispatcher_.assignNewLabel(decl, mangledName(decl));
|
||||
if (!dispatcher_.shouldEmitDeclBody(decl)) {
|
||||
return EnumElementDeclsTrap{id, decl.getNameStr().str()};
|
||||
}
|
||||
EnumElementDecl entry{id};
|
||||
entry.name = decl.getNameStr().str();
|
||||
if (decl.hasParameterList()) {
|
||||
entry.params = dispatcher_.fetchRepeatedLabels(*decl.getParameterList());
|
||||
}
|
||||
fillValueDecl(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
const swift::EnumElementDecl& decl);
|
||||
codeql::GenericTypeParamDecl translateGenericTypeParamDecl(
|
||||
const swift::GenericTypeParamDecl& decl) {
|
||||
// TODO: deduplicate
|
||||
GenericTypeParamDecl entry{dispatcher_.assignNewLabel(decl)};
|
||||
fillTypeDecl(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
const swift::GenericTypeParamDecl& decl);
|
||||
std::variant<codeql::AssociatedTypeDecl, codeql::AssociatedTypeDeclsTrap>
|
||||
translateAssociatedTypeDecl(const swift::AssociatedTypeDecl& decl) {
|
||||
auto id = dispatcher_.assignNewLabel(decl, mangledName(decl));
|
||||
if (!dispatcher_.shouldEmitDeclBody(decl)) {
|
||||
return AssociatedTypeDeclsTrap{id};
|
||||
}
|
||||
AssociatedTypeDecl entry{id};
|
||||
fillTypeDecl(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
translateAssociatedTypeDecl(const swift::AssociatedTypeDecl& decl);
|
||||
std::variant<codeql::TypeAliasDecl, codeql::TypeAliasDeclsTrap> translateTypeAliasDecl(
|
||||
const swift::TypeAliasDecl& decl) {
|
||||
auto id = dispatcher_.assignNewLabel(decl, mangledName(decl));
|
||||
if (!dispatcher_.shouldEmitDeclBody(decl)) {
|
||||
return TypeAliasDeclsTrap{id};
|
||||
}
|
||||
TypeAliasDecl entry{id};
|
||||
fillTypeDecl(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
const swift::TypeAliasDecl& decl);
|
||||
std::variant<codeql::AccessorDecl, codeql::AccessorDeclsTrap> translateAccessorDecl(
|
||||
const swift::AccessorDecl& decl) {
|
||||
auto id = dispatcher_.assignNewLabel(decl, mangledName(decl));
|
||||
if (!dispatcher_.shouldEmitDeclBody(decl)) {
|
||||
return AccessorDeclsTrap{id};
|
||||
}
|
||||
AccessorDecl entry{id};
|
||||
switch (decl.getAccessorKind()) {
|
||||
case swift::AccessorKind::Get:
|
||||
entry.is_getter = true;
|
||||
break;
|
||||
case swift::AccessorKind::Set:
|
||||
entry.is_setter = true;
|
||||
break;
|
||||
case swift::AccessorKind::WillSet:
|
||||
entry.is_will_set = true;
|
||||
break;
|
||||
case swift::AccessorKind::DidSet:
|
||||
entry.is_did_set = true;
|
||||
break;
|
||||
}
|
||||
fillAbstractFunctionDecl(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
std::optional<codeql::SubscriptDecl> translateSubscriptDecl(const swift::SubscriptDecl& decl) {
|
||||
auto id = dispatcher_.assignNewLabel(decl, mangledName(decl));
|
||||
if (!dispatcher_.shouldEmitDeclBody(decl)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
SubscriptDecl entry{id};
|
||||
entry.element_type = dispatcher_.fetchLabel(decl.getElementInterfaceType());
|
||||
if (auto indices = decl.getIndices()) {
|
||||
entry.params = dispatcher_.fetchRepeatedLabels(*indices);
|
||||
}
|
||||
fillAbstractStorageDecl(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::ExtensionDecl translateExtensionDecl(const swift::ExtensionDecl& decl) {
|
||||
ExtensionDecl entry{dispatcher_.assignNewLabel(decl)};
|
||||
entry.extended_type_decl = dispatcher_.fetchLabel(decl.getExtendedNominal());
|
||||
fillGenericContext(decl, entry);
|
||||
fillIterableDeclContext(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
const swift::AccessorDecl& decl);
|
||||
std::optional<codeql::SubscriptDecl> translateSubscriptDecl(const swift::SubscriptDecl& decl);
|
||||
codeql::ExtensionDecl translateExtensionDecl(const swift::ExtensionDecl& decl);
|
||||
|
||||
private:
|
||||
std::string mangledName(const swift::ValueDecl& decl) {
|
||||
// prefix adds a couple of special symbols, we don't necessary need them
|
||||
return mangler.mangleAnyDecl(&decl, /* prefix = */ false);
|
||||
}
|
||||
|
||||
std::string mangledName(const swift::ValueDecl& decl);
|
||||
void fillAbstractFunctionDecl(const swift::AbstractFunctionDecl& decl,
|
||||
codeql::AbstractFunctionDecl& entry) {
|
||||
assert(decl.hasParameterList() && "Expect functions to have a parameter list");
|
||||
entry.name = !decl.hasName() ? "(unnamed function decl)" : constructName(decl.getName());
|
||||
entry.body = dispatcher_.fetchOptionalLabel(decl.getBody());
|
||||
entry.params = dispatcher_.fetchRepeatedLabels(*decl.getParameters());
|
||||
fillValueDecl(decl, entry);
|
||||
fillGenericContext(decl, entry);
|
||||
}
|
||||
|
||||
void fillOperatorDecl(const swift::OperatorDecl& decl, codeql::OperatorDecl& entry) {
|
||||
entry.name = decl.getName().str().str();
|
||||
}
|
||||
|
||||
void fillTypeDecl(const swift::TypeDecl& decl, codeql::TypeDecl& entry) {
|
||||
entry.name = decl.getNameStr().str();
|
||||
for (auto& typeLoc : decl.getInherited()) {
|
||||
if (auto type = typeLoc.getType()) {
|
||||
entry.base_types.push_back(dispatcher_.fetchLabel(type));
|
||||
}
|
||||
}
|
||||
fillValueDecl(decl, entry);
|
||||
}
|
||||
|
||||
codeql::AbstractFunctionDecl& entry);
|
||||
void fillOperatorDecl(const swift::OperatorDecl& decl, codeql::OperatorDecl& entry);
|
||||
void fillTypeDecl(const swift::TypeDecl& decl, codeql::TypeDecl& entry);
|
||||
void fillIterableDeclContext(const swift::IterableDeclContext& decl,
|
||||
codeql::IterableDeclContext& entry) {
|
||||
entry.members = dispatcher_.fetchRepeatedLabels(decl.getAllMembers());
|
||||
}
|
||||
|
||||
void fillVarDecl(const swift::VarDecl& decl, codeql::VarDecl& entry) {
|
||||
entry.name = decl.getNameStr().str();
|
||||
entry.type = dispatcher_.fetchLabel(decl.getType());
|
||||
entry.parent_pattern = dispatcher_.fetchOptionalLabel(decl.getParentPattern());
|
||||
entry.parent_initializer = dispatcher_.fetchOptionalLabel(decl.getParentInitializer());
|
||||
if (decl.hasAttachedPropertyWrapper()) {
|
||||
entry.attached_property_wrapper_type =
|
||||
dispatcher_.fetchOptionalLabel(decl.getPropertyWrapperBackingPropertyType());
|
||||
}
|
||||
fillAbstractStorageDecl(decl, entry);
|
||||
}
|
||||
|
||||
void fillNominalTypeDecl(const swift::NominalTypeDecl& decl, codeql::NominalTypeDecl& entry) {
|
||||
entry.type = dispatcher_.fetchLabel(decl.getDeclaredType());
|
||||
fillGenericContext(decl, entry);
|
||||
fillIterableDeclContext(decl, entry);
|
||||
fillTypeDecl(decl, entry);
|
||||
}
|
||||
|
||||
void fillGenericContext(const swift::GenericContext& decl, codeql::GenericContext& entry) {
|
||||
if (auto params = decl.getGenericParams()) {
|
||||
entry.generic_type_params = dispatcher_.fetchRepeatedLabels(*params);
|
||||
}
|
||||
}
|
||||
|
||||
void fillValueDecl(const swift::ValueDecl& decl, codeql::ValueDecl& entry) {
|
||||
assert(decl.getInterfaceType() && "Expect ValueDecl to have InterfaceType");
|
||||
entry.interface_type = dispatcher_.fetchLabel(decl.getInterfaceType());
|
||||
}
|
||||
|
||||
codeql::IterableDeclContext& entry);
|
||||
void fillVarDecl(const swift::VarDecl& decl, codeql::VarDecl& entry);
|
||||
void fillNominalTypeDecl(const swift::NominalTypeDecl& decl, codeql::NominalTypeDecl& entry);
|
||||
void fillGenericContext(const swift::GenericContext& decl, codeql::GenericContext& entry);
|
||||
void fillValueDecl(const swift::ValueDecl& decl, codeql::ValueDecl& entry);
|
||||
void fillAbstractStorageDecl(const swift::AbstractStorageDecl& decl,
|
||||
codeql::AbstractStorageDecl& entry) {
|
||||
entry.accessor_decls = dispatcher_.fetchRepeatedLabels(decl.getAllAccessors());
|
||||
fillValueDecl(decl, entry);
|
||||
}
|
||||
|
||||
// Constructs a `std::string` of the form `f(x:y:)` for a declaration
|
||||
// like `func f(x first: Int, y second: Int) { }`
|
||||
std::string constructName(const swift::DeclName& declName) {
|
||||
std::string name = declName.getBaseName().userFacingName().str();
|
||||
name += "(";
|
||||
for (const auto& argName : declName.getArgumentNames()) {
|
||||
if (argName.empty()) {
|
||||
name += "_:";
|
||||
} else {
|
||||
name += argName.str().str() + ":";
|
||||
}
|
||||
}
|
||||
name += ")";
|
||||
return name;
|
||||
}
|
||||
codeql::AbstractStorageDecl& entry);
|
||||
|
||||
private:
|
||||
swift::Mangle::ASTMangler mangler;
|
||||
|
||||
671
swift/extractor/visitors/ExprVisitor.cpp
Normal file
671
swift/extractor/visitors/ExprVisitor.cpp
Normal file
@@ -0,0 +1,671 @@
|
||||
#include "swift/extractor/visitors/ExprVisitor.h"
|
||||
|
||||
#include <swift/AST/ParameterList.h>
|
||||
|
||||
namespace codeql {
|
||||
|
||||
template <typename DirectToStorage,
|
||||
typename DirectToImplementation,
|
||||
typename Ordinary,
|
||||
typename T,
|
||||
typename Label>
|
||||
void ExprVisitor::emitAccessorSemantics(T* ast, Label label) {
|
||||
switch (ast->getAccessSemantics()) {
|
||||
case swift::AccessSemantics::DirectToStorage:
|
||||
dispatcher_.emit(DirectToStorage{label});
|
||||
break;
|
||||
case swift::AccessSemantics::DirectToImplementation:
|
||||
dispatcher_.emit(DirectToImplementation{label});
|
||||
break;
|
||||
case swift::AccessSemantics::Ordinary:
|
||||
dispatcher_.emit(Ordinary{label});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ExprVisitor::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 ExprVisitor::visitIntegerLiteralExpr(swift::IntegerLiteralExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
auto value = (expr->isNegative() ? "-" : "") + expr->getDigitsText().str();
|
||||
dispatcher_.emit(IntegerLiteralExprsTrap{label, value});
|
||||
}
|
||||
|
||||
void ExprVisitor::visitFloatLiteralExpr(swift::FloatLiteralExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
auto value = (expr->isNegative() ? "-" : "") + expr->getDigitsText().str();
|
||||
dispatcher_.emit(FloatLiteralExprsTrap{label, value});
|
||||
}
|
||||
|
||||
void ExprVisitor::visitBooleanLiteralExpr(swift::BooleanLiteralExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(BooleanLiteralExprsTrap{label, expr->getValue()});
|
||||
}
|
||||
|
||||
void ExprVisitor::visitMagicIdentifierLiteralExpr(swift::MagicIdentifierLiteralExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
auto kind = swift::MagicIdentifierLiteralExpr::getKindString(expr->getKind()).str();
|
||||
dispatcher_.emit(MagicIdentifierLiteralExprsTrap{label, kind});
|
||||
}
|
||||
|
||||
void ExprVisitor::visitStringLiteralExpr(swift::StringLiteralExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(StringLiteralExprsTrap{label, expr->getValue().str()});
|
||||
}
|
||||
|
||||
void ExprVisitor::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 ExprVisitor::visitNilLiteralExpr(swift::NilLiteralExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(NilLiteralExprsTrap{label});
|
||||
}
|
||||
|
||||
void ExprVisitor::visitCallExpr(swift::CallExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(CallExprsTrap{label});
|
||||
emitApplyExpr(expr, label);
|
||||
}
|
||||
|
||||
void ExprVisitor::visitPrefixUnaryExpr(swift::PrefixUnaryExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(PrefixUnaryExprsTrap{label});
|
||||
emitApplyExpr(expr, label);
|
||||
}
|
||||
|
||||
void ExprVisitor::visitDeclRefExpr(swift::DeclRefExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(DeclRefExprsTrap{label, dispatcher_.fetchLabel(expr->getDecl())});
|
||||
emitAccessorSemantics<DeclRefExprHasDirectToStorageSemanticsTrap,
|
||||
DeclRefExprHasDirectToImplementationSemanticsTrap,
|
||||
DeclRefExprHasOrdinarySemanticsTrap>(expr, label);
|
||||
auto i = 0u;
|
||||
for (auto t : expr->getDeclRef().getSubstitutions().getReplacementTypes()) {
|
||||
dispatcher_.emit(DeclRefExprReplacementTypesTrap{label, i++, dispatcher_.fetchLabel(t)});
|
||||
}
|
||||
}
|
||||
|
||||
void ExprVisitor::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 ExprVisitor::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 ExprVisitor::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 ExprVisitor::visitBinaryExpr(swift::BinaryExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(BinaryExprsTrap{label});
|
||||
emitApplyExpr(expr, label);
|
||||
}
|
||||
|
||||
void ExprVisitor::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 ExprVisitor::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 ExprVisitor::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 ExprVisitor::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 ExprVisitor::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 ExprVisitor::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 ExprVisitor::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 ExprVisitor::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 ExprVisitor::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 ExprVisitor::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 ExprVisitor::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 ExprVisitor::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 ExprVisitor::visitDotSyntaxCallExpr(swift::DotSyntaxCallExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(DotSyntaxCallExprsTrap{label});
|
||||
emitSelfApplyExpr(expr, label);
|
||||
}
|
||||
|
||||
void ExprVisitor::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 ExprVisitor::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 ExprVisitor::visitErasureExpr(swift::ErasureExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(ErasureExprsTrap{label});
|
||||
emitImplicitConversionExpr(expr, label);
|
||||
}
|
||||
|
||||
codeql::TypeExpr ExprVisitor::translateTypeExpr(const swift::TypeExpr& expr) {
|
||||
TypeExpr entry{dispatcher_.assignNewLabel(expr)};
|
||||
entry.type_repr = dispatcher_.fetchOptionalLabel(expr.getTypeRepr());
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::ParenExpr ExprVisitor::translateParenExpr(const swift::ParenExpr& expr) {
|
||||
ParenExpr entry{dispatcher_.assignNewLabel(expr)};
|
||||
fillIdentityExpr(expr, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
void ExprVisitor::visitLoadExpr(swift::LoadExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(LoadExprsTrap{label});
|
||||
emitImplicitConversionExpr(expr, label);
|
||||
}
|
||||
|
||||
void ExprVisitor::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 ExprVisitor::visitOpaqueValueExpr(swift::OpaqueValueExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(OpaqueValueExprsTrap{label});
|
||||
}
|
||||
|
||||
void ExprVisitor::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, bodyLabel, varLabel});
|
||||
if (auto subExpr = expr->getSubExpr()) {
|
||||
dispatcher_.emit(TapExprSubExprsTrap{label, dispatcher_.fetchLabel(subExpr)});
|
||||
}
|
||||
}
|
||||
|
||||
void ExprVisitor::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 ExprVisitor::visitTryExpr(swift::TryExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(TryExprsTrap{label});
|
||||
emitAnyTryExpr(expr, label);
|
||||
}
|
||||
|
||||
void ExprVisitor::visitForceTryExpr(swift::ForceTryExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(ForceTryExprsTrap{label});
|
||||
emitAnyTryExpr(expr, label);
|
||||
}
|
||||
|
||||
void ExprVisitor::visitOptionalTryExpr(swift::OptionalTryExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(OptionalTryExprsTrap{label});
|
||||
emitAnyTryExpr(expr, label);
|
||||
}
|
||||
|
||||
void ExprVisitor::visitInjectIntoOptionalExpr(swift::InjectIntoOptionalExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(InjectIntoOptionalExprsTrap{label});
|
||||
emitImplicitConversionExpr(expr, label);
|
||||
}
|
||||
|
||||
void ExprVisitor::visitConstructorRefCallExpr(swift::ConstructorRefCallExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(ConstructorRefCallExprsTrap{label});
|
||||
emitSelfApplyExpr(expr, label);
|
||||
}
|
||||
|
||||
void ExprVisitor::visitDiscardAssignmentExpr(swift::DiscardAssignmentExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(DiscardAssignmentExprsTrap{label});
|
||||
}
|
||||
|
||||
codeql::ClosureExpr ExprVisitor::translateClosureExpr(const swift::ClosureExpr& expr) {
|
||||
ClosureExpr entry{dispatcher_.assignNewLabel(expr)};
|
||||
fillAbstractClosureExpr(expr, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::AutoClosureExpr ExprVisitor::translateAutoClosureExpr(const swift::AutoClosureExpr& expr) {
|
||||
AutoClosureExpr entry{dispatcher_.assignNewLabel(expr)};
|
||||
fillAbstractClosureExpr(expr, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
void ExprVisitor::visitCoerceExpr(swift::CoerceExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(CoerceExprsTrap{label});
|
||||
emitExplicitCastExpr(expr, label);
|
||||
}
|
||||
|
||||
void ExprVisitor::visitConditionalCheckedCastExpr(swift::ConditionalCheckedCastExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(ConditionalCheckedCastExprsTrap{label});
|
||||
emitExplicitCastExpr(expr, label);
|
||||
}
|
||||
|
||||
void ExprVisitor::visitForcedCheckedCastExpr(swift::ForcedCheckedCastExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(ForcedCheckedCastExprsTrap{label});
|
||||
emitExplicitCastExpr(expr, label);
|
||||
}
|
||||
|
||||
void ExprVisitor::visitIsExpr(swift::IsExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(IsExprsTrap{label});
|
||||
emitExplicitCastExpr(expr, label);
|
||||
}
|
||||
|
||||
void ExprVisitor::visitLookupExpr(swift::LookupExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
emitLookupExpr(expr, label);
|
||||
}
|
||||
|
||||
void ExprVisitor::visitSubscriptExpr(swift::SubscriptExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(SubscriptExprsTrap{label});
|
||||
|
||||
emitAccessorSemantics<SubscriptExprHasDirectToStorageSemanticsTrap,
|
||||
SubscriptExprHasDirectToImplementationSemanticsTrap,
|
||||
SubscriptExprHasOrdinarySemanticsTrap>(expr, label);
|
||||
|
||||
auto i = 0u;
|
||||
for (const auto& arg : *expr->getArgs()) {
|
||||
dispatcher_.emit(SubscriptExprArgumentsTrap{label, i++, emitArgument(arg)});
|
||||
}
|
||||
emitLookupExpr(expr, label);
|
||||
}
|
||||
|
||||
void ExprVisitor::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 ExprVisitor::visitFunctionConversionExpr(swift::FunctionConversionExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(FunctionConversionExprsTrap{label});
|
||||
emitImplicitConversionExpr(expr, label);
|
||||
}
|
||||
|
||||
void ExprVisitor::visitInOutToPointerExpr(swift::InOutToPointerExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(InOutToPointerExprsTrap{label});
|
||||
emitImplicitConversionExpr(expr, label);
|
||||
}
|
||||
|
||||
void ExprVisitor::visitMemberRefExpr(swift::MemberRefExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(MemberRefExprsTrap{label});
|
||||
|
||||
emitAccessorSemantics<MemberRefExprHasDirectToStorageSemanticsTrap,
|
||||
MemberRefExprHasDirectToImplementationSemanticsTrap,
|
||||
MemberRefExprHasOrdinarySemanticsTrap>(expr, label);
|
||||
|
||||
emitLookupExpr(expr, label);
|
||||
}
|
||||
|
||||
void ExprVisitor::visitDerivedToBaseExpr(swift::DerivedToBaseExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(DerivedToBaseExprsTrap{label});
|
||||
emitImplicitConversionExpr(expr, label);
|
||||
}
|
||||
|
||||
void ExprVisitor::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->getParsedRoot()) {
|
||||
auto rootLabel = dispatcher_.fetchLabel(root);
|
||||
dispatcher_.emit(KeyPathExprParsedRootsTrap{label, rootLabel});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ExprVisitor::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 ExprVisitor::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 ExprVisitor::visitPointerToPointerExpr(swift::PointerToPointerExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(PointerToPointerExprsTrap{label});
|
||||
emitImplicitConversionExpr(expr, label);
|
||||
}
|
||||
|
||||
void ExprVisitor::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});
|
||||
}
|
||||
|
||||
void ExprVisitor::visitKeyPathDotExpr(swift::KeyPathDotExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(KeyPathDotExprsTrap{label});
|
||||
}
|
||||
|
||||
void ExprVisitor::visitKeyPathApplicationExpr(swift::KeyPathApplicationExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
assert(expr->getBase() && "KeyPathApplicationExpr has getBase()");
|
||||
assert(expr->getKeyPath() && "KeyPathApplicationExpr has getKeyPath()");
|
||||
|
||||
auto baseLabel = dispatcher_.fetchLabel(expr->getBase());
|
||||
auto keyPathLabel = dispatcher_.fetchLabel(expr->getKeyPath());
|
||||
|
||||
dispatcher_.emit(KeyPathApplicationExprsTrap{label, baseLabel, keyPathLabel});
|
||||
}
|
||||
|
||||
void ExprVisitor::visitOtherConstructorDeclRefExpr(swift::OtherConstructorDeclRefExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
assert(expr->getDecl() && "OtherConstructorDeclRefExpr has getDecl()");
|
||||
|
||||
auto ctorLabel = dispatcher_.fetchLabel(expr->getDecl());
|
||||
dispatcher_.emit(OtherConstructorDeclRefExprsTrap{label, ctorLabel});
|
||||
}
|
||||
|
||||
codeql::UnresolvedDeclRefExpr ExprVisitor::translateUnresolvedDeclRefExpr(
|
||||
const swift::UnresolvedDeclRefExpr& expr) {
|
||||
codeql::UnresolvedDeclRefExpr entry{dispatcher_.assignNewLabel(expr)};
|
||||
if (expr.hasName()) {
|
||||
llvm::SmallVector<char> scratch;
|
||||
entry.name = expr.getName().getString(scratch).str();
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::UnresolvedDotExpr ExprVisitor::translateUnresolvedDotExpr(
|
||||
const swift::UnresolvedDotExpr& expr) {
|
||||
codeql::UnresolvedDotExpr entry{dispatcher_.assignNewLabel(expr)};
|
||||
assert(expr.getBase() && "Expect UnresolvedDotExpr to have a base");
|
||||
entry.base = dispatcher_.fetchLabel(expr.getBase());
|
||||
llvm::SmallVector<char> scratch;
|
||||
entry.name = expr.getName().getString(scratch).str();
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::UnresolvedMemberExpr ExprVisitor::translateUnresolvedMemberExpr(
|
||||
const swift::UnresolvedMemberExpr& expr) {
|
||||
UnresolvedMemberExpr entry{dispatcher_.assignNewLabel(expr)};
|
||||
llvm::SmallVector<char> scratch;
|
||||
entry.name = expr.getName().getString(scratch).str();
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::SequenceExpr ExprVisitor::translateSequenceExpr(const swift::SequenceExpr& expr) {
|
||||
SequenceExpr entry{dispatcher_.assignNewLabel(expr)};
|
||||
entry.elements = dispatcher_.fetchRepeatedLabels(expr.getElements());
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::BridgeToObjCExpr ExprVisitor::translateBridgeToObjCExpr(
|
||||
const swift::BridgeToObjCExpr& expr) {
|
||||
BridgeToObjCExpr entry{dispatcher_.assignNewLabel(expr)};
|
||||
entry.sub_expr = dispatcher_.fetchLabel(expr.getSubExpr());
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::BridgeFromObjCExpr ExprVisitor::translateBridgeFromObjCExpr(
|
||||
const swift::BridgeFromObjCExpr& expr) {
|
||||
BridgeFromObjCExpr entry{dispatcher_.assignNewLabel(expr)};
|
||||
entry.sub_expr = dispatcher_.fetchLabel(expr.getSubExpr());
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::DotSelfExpr ExprVisitor::translateDotSelfExpr(const swift::DotSelfExpr& expr) {
|
||||
DotSelfExpr entry{dispatcher_.assignNewLabel(expr)};
|
||||
fillIdentityExpr(expr, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::ErrorExpr ExprVisitor::translateErrorExpr(const swift::ErrorExpr& expr) {
|
||||
ErrorExpr entry{dispatcher_.assignNewLabel(expr)};
|
||||
return entry;
|
||||
}
|
||||
|
||||
void ExprVisitor::fillAbstractClosureExpr(const swift::AbstractClosureExpr& expr,
|
||||
codeql::AbstractClosureExpr& entry) {
|
||||
assert(expr.getParameters() && "AbstractClosureExpr has getParameters()");
|
||||
assert(expr.getBody() && "AbstractClosureExpr has getBody()");
|
||||
entry.params = dispatcher_.fetchRepeatedLabels(*expr.getParameters());
|
||||
entry.body = dispatcher_.fetchLabel(expr.getBody());
|
||||
}
|
||||
|
||||
TrapLabel<ArgumentTag> ExprVisitor::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 ExprVisitor::emitImplicitConversionExpr(swift::ImplicitConversionExpr* expr,
|
||||
TrapLabel<ImplicitConversionExprTag> label) {
|
||||
assert(expr->getSubExpr() && "ImplicitConversionExpr has getSubExpr()");
|
||||
dispatcher_.emit(ImplicitConversionExprsTrap{label, dispatcher_.fetchLabel(expr->getSubExpr())});
|
||||
}
|
||||
|
||||
void ExprVisitor::emitExplicitCastExpr(swift::ExplicitCastExpr* expr,
|
||||
TrapLabel<ExplicitCastExprTag> label) {
|
||||
assert(expr->getSubExpr() && "ExplicitCastExpr has getSubExpr()");
|
||||
dispatcher_.emit(ExplicitCastExprsTrap{label, dispatcher_.fetchLabel(expr->getSubExpr())});
|
||||
}
|
||||
|
||||
void ExprVisitor::fillIdentityExpr(const swift::IdentityExpr& expr, codeql::IdentityExpr& entry) {
|
||||
assert(expr.getSubExpr() && "IdentityExpr has getSubExpr()");
|
||||
entry.sub_expr = dispatcher_.fetchLabel(expr.getSubExpr());
|
||||
}
|
||||
|
||||
void ExprVisitor::emitAnyTryExpr(swift::AnyTryExpr* expr, TrapLabel<AnyTryExprTag> label) {
|
||||
assert(expr->getSubExpr() && "AnyTryExpr has getSubExpr()");
|
||||
dispatcher_.emit(AnyTryExprsTrap{label, dispatcher_.fetchLabel(expr->getSubExpr())});
|
||||
}
|
||||
|
||||
void ExprVisitor::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 ExprVisitor::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);
|
||||
}
|
||||
|
||||
void ExprVisitor::emitLookupExpr(const swift::LookupExpr* expr, TrapLabel<LookupExprTag> label) {
|
||||
assert(expr->getBase() && "LookupExpr has getBase()");
|
||||
auto baseLabel = dispatcher_.fetchLabel(expr->getBase());
|
||||
dispatcher_.emit(LookupExprsTrap{label, baseLabel});
|
||||
if (expr->hasDecl()) {
|
||||
auto declLabel = dispatcher_.fetchLabel(expr->getDecl().getDecl());
|
||||
dispatcher_.emit(LookupExprMembersTrap{label, declLabel});
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace codeql
|
||||
@@ -8,647 +8,94 @@ class ExprVisitor : public AstVisitorBase<ExprVisitor> {
|
||||
public:
|
||||
using AstVisitorBase<ExprVisitor>::AstVisitorBase;
|
||||
|
||||
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())});
|
||||
emitAccessorSemantics<DeclRefExprHasDirectToStorageSemanticsTrap,
|
||||
DeclRefExprHasDirectToImplementationSemanticsTrap,
|
||||
DeclRefExprHasOrdinarySemanticsTrap>(expr, label);
|
||||
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);
|
||||
}
|
||||
|
||||
codeql::TypeExpr translateTypeExpr(const swift::TypeExpr& expr) {
|
||||
TypeExpr entry{dispatcher_.assignNewLabel(expr)};
|
||||
entry.type_repr = dispatcher_.fetchOptionalLabel(expr.getTypeRepr());
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::ParenExpr translateParenExpr(const swift::ParenExpr& expr) {
|
||||
ParenExpr entry{dispatcher_.assignNewLabel(expr)};
|
||||
fillIdentityExpr(expr, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
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, bodyLabel, varLabel});
|
||||
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});
|
||||
}
|
||||
|
||||
codeql::ClosureExpr translateClosureExpr(const swift::ClosureExpr& expr) {
|
||||
ClosureExpr entry{dispatcher_.assignNewLabel(expr)};
|
||||
fillAbstractClosureExpr(expr, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::AutoClosureExpr translateAutoClosureExpr(const swift::AutoClosureExpr& expr) {
|
||||
AutoClosureExpr entry{dispatcher_.assignNewLabel(expr)};
|
||||
fillAbstractClosureExpr(expr, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
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 visitLookupExpr(swift::LookupExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
emitLookupExpr(expr, label);
|
||||
}
|
||||
|
||||
void visitSubscriptExpr(swift::SubscriptExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(SubscriptExprsTrap{label});
|
||||
|
||||
emitAccessorSemantics<SubscriptExprHasDirectToStorageSemanticsTrap,
|
||||
SubscriptExprHasDirectToImplementationSemanticsTrap,
|
||||
SubscriptExprHasOrdinarySemanticsTrap>(expr, label);
|
||||
|
||||
auto i = 0u;
|
||||
for (const auto& arg : *expr->getArgs()) {
|
||||
dispatcher_.emit(SubscriptExprArgumentsTrap{label, i++, emitArgument(arg)});
|
||||
}
|
||||
emitLookupExpr(expr, label);
|
||||
}
|
||||
|
||||
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);
|
||||
dispatcher_.emit(MemberRefExprsTrap{label});
|
||||
|
||||
emitAccessorSemantics<MemberRefExprHasDirectToStorageSemanticsTrap,
|
||||
MemberRefExprHasDirectToImplementationSemanticsTrap,
|
||||
MemberRefExprHasOrdinarySemanticsTrap>(expr, label);
|
||||
|
||||
emitLookupExpr(expr, label);
|
||||
}
|
||||
|
||||
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->getParsedRoot()) {
|
||||
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});
|
||||
}
|
||||
|
||||
void visitKeyPathDotExpr(swift::KeyPathDotExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
dispatcher_.emit(KeyPathDotExprsTrap{label});
|
||||
}
|
||||
|
||||
void visitKeyPathApplicationExpr(swift::KeyPathApplicationExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
assert(expr->getBase() && "KeyPathApplicationExpr has getBase()");
|
||||
assert(expr->getKeyPath() && "KeyPathApplicationExpr has getKeyPath()");
|
||||
|
||||
auto baseLabel = dispatcher_.fetchLabel(expr->getBase());
|
||||
auto keyPathLabel = dispatcher_.fetchLabel(expr->getKeyPath());
|
||||
|
||||
dispatcher_.emit(KeyPathApplicationExprsTrap{label, baseLabel, keyPathLabel});
|
||||
}
|
||||
|
||||
void visitOtherConstructorDeclRefExpr(swift::OtherConstructorDeclRefExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
assert(expr->getDecl() && "OtherConstructorDeclRefExpr has getDecl()");
|
||||
|
||||
auto ctorLabel = dispatcher_.fetchLabel(expr->getDecl());
|
||||
dispatcher_.emit(OtherConstructorDeclRefExprsTrap{label, ctorLabel});
|
||||
}
|
||||
|
||||
void visit(swift::Expr* expr);
|
||||
void visitIntegerLiteralExpr(swift::IntegerLiteralExpr* expr);
|
||||
void visitFloatLiteralExpr(swift::FloatLiteralExpr* expr);
|
||||
void visitBooleanLiteralExpr(swift::BooleanLiteralExpr* expr);
|
||||
void visitMagicIdentifierLiteralExpr(swift::MagicIdentifierLiteralExpr* expr);
|
||||
void visitStringLiteralExpr(swift::StringLiteralExpr* expr);
|
||||
void visitInterpolatedStringLiteralExpr(swift::InterpolatedStringLiteralExpr* expr);
|
||||
void visitNilLiteralExpr(swift::NilLiteralExpr* expr);
|
||||
void visitCallExpr(swift::CallExpr* expr);
|
||||
void visitPrefixUnaryExpr(swift::PrefixUnaryExpr* expr);
|
||||
void visitDeclRefExpr(swift::DeclRefExpr* expr);
|
||||
void visitAssignExpr(swift::AssignExpr* expr);
|
||||
void visitBindOptionalExpr(swift::BindOptionalExpr* expr);
|
||||
void visitCaptureListExpr(swift::CaptureListExpr* expr);
|
||||
void visitBinaryExpr(swift::BinaryExpr* expr);
|
||||
void visitTupleExpr(swift::TupleExpr* expr);
|
||||
void visitDefaultArgumentExpr(swift::DefaultArgumentExpr* expr);
|
||||
void visitDotSyntaxBaseIgnoredExpr(swift::DotSyntaxBaseIgnoredExpr* expr);
|
||||
void visitDynamicTypeExpr(swift::DynamicTypeExpr* expr);
|
||||
void visitEnumIsCaseExpr(swift::EnumIsCaseExpr* expr);
|
||||
void visitMakeTemporarilyEscapableExpr(swift::MakeTemporarilyEscapableExpr* expr);
|
||||
void visitObjCSelectorExpr(swift::ObjCSelectorExpr* expr);
|
||||
void visitOneWayExpr(swift::OneWayExpr* expr);
|
||||
void visitOpenExistentialExpr(swift::OpenExistentialExpr* expr);
|
||||
void visitOptionalEvaluationExpr(swift::OptionalEvaluationExpr* expr);
|
||||
void visitRebindSelfInConstructorExpr(swift::RebindSelfInConstructorExpr* expr);
|
||||
void visitSuperRefExpr(swift::SuperRefExpr* expr);
|
||||
void visitDotSyntaxCallExpr(swift::DotSyntaxCallExpr* expr);
|
||||
void visitVarargExpansionExpr(swift::VarargExpansionExpr* expr);
|
||||
void visitArrayExpr(swift::ArrayExpr* expr);
|
||||
void visitErasureExpr(swift::ErasureExpr* expr);
|
||||
codeql::TypeExpr translateTypeExpr(const swift::TypeExpr& expr);
|
||||
codeql::ParenExpr translateParenExpr(const swift::ParenExpr& expr);
|
||||
void visitLoadExpr(swift::LoadExpr* expr);
|
||||
void visitInOutExpr(swift::InOutExpr* expr);
|
||||
void visitOpaqueValueExpr(swift::OpaqueValueExpr* expr);
|
||||
void visitTapExpr(swift::TapExpr* expr);
|
||||
void visitTupleElementExpr(swift::TupleElementExpr* expr);
|
||||
void visitTryExpr(swift::TryExpr* expr);
|
||||
void visitForceTryExpr(swift::ForceTryExpr* expr);
|
||||
void visitOptionalTryExpr(swift::OptionalTryExpr* expr);
|
||||
void visitInjectIntoOptionalExpr(swift::InjectIntoOptionalExpr* expr);
|
||||
void visitConstructorRefCallExpr(swift::ConstructorRefCallExpr* expr);
|
||||
void visitDiscardAssignmentExpr(swift::DiscardAssignmentExpr* expr);
|
||||
codeql::ClosureExpr translateClosureExpr(const swift::ClosureExpr& expr);
|
||||
codeql::AutoClosureExpr translateAutoClosureExpr(const swift::AutoClosureExpr& expr);
|
||||
void visitCoerceExpr(swift::CoerceExpr* expr);
|
||||
void visitConditionalCheckedCastExpr(swift::ConditionalCheckedCastExpr* expr);
|
||||
void visitForcedCheckedCastExpr(swift::ForcedCheckedCastExpr* expr);
|
||||
void visitIsExpr(swift::IsExpr* expr);
|
||||
void visitLookupExpr(swift::LookupExpr* expr);
|
||||
void visitSubscriptExpr(swift::SubscriptExpr* expr);
|
||||
void visitDictionaryExpr(swift::DictionaryExpr* expr);
|
||||
void visitFunctionConversionExpr(swift::FunctionConversionExpr* expr);
|
||||
void visitInOutToPointerExpr(swift::InOutToPointerExpr* expr);
|
||||
void visitMemberRefExpr(swift::MemberRefExpr* expr);
|
||||
void visitDerivedToBaseExpr(swift::DerivedToBaseExpr* expr);
|
||||
void visitKeyPathExpr(swift::KeyPathExpr* expr);
|
||||
void visitLazyInitializerExpr(swift::LazyInitializerExpr* expr);
|
||||
void visitForceValueExpr(swift::ForceValueExpr* expr);
|
||||
void visitPointerToPointerExpr(swift::PointerToPointerExpr* expr);
|
||||
void visitIfExpr(swift::IfExpr* expr);
|
||||
void visitKeyPathDotExpr(swift::KeyPathDotExpr* expr);
|
||||
void visitKeyPathApplicationExpr(swift::KeyPathApplicationExpr* expr);
|
||||
void visitOtherConstructorDeclRefExpr(swift::OtherConstructorDeclRefExpr* expr);
|
||||
codeql::UnresolvedDeclRefExpr translateUnresolvedDeclRefExpr(
|
||||
const swift::UnresolvedDeclRefExpr& expr) {
|
||||
codeql::UnresolvedDeclRefExpr entry{dispatcher_.assignNewLabel(expr)};
|
||||
if (expr.hasName()) {
|
||||
llvm::SmallVector<char> scratch;
|
||||
entry.name = expr.getName().getString(scratch).str();
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::UnresolvedDotExpr translateUnresolvedDotExpr(const swift::UnresolvedDotExpr& expr) {
|
||||
codeql::UnresolvedDotExpr entry{dispatcher_.assignNewLabel(expr)};
|
||||
assert(expr.getBase() && "Expect UnresolvedDotExpr to have a base");
|
||||
entry.base = dispatcher_.fetchLabel(expr.getBase());
|
||||
llvm::SmallVector<char> scratch;
|
||||
entry.name = expr.getName().getString(scratch).str();
|
||||
return entry;
|
||||
}
|
||||
|
||||
const swift::UnresolvedDeclRefExpr& expr);
|
||||
codeql::UnresolvedDotExpr translateUnresolvedDotExpr(const swift::UnresolvedDotExpr& expr);
|
||||
codeql::UnresolvedMemberExpr translateUnresolvedMemberExpr(
|
||||
const swift::UnresolvedMemberExpr& expr) {
|
||||
UnresolvedMemberExpr entry{dispatcher_.assignNewLabel(expr)};
|
||||
llvm::SmallVector<char> scratch;
|
||||
entry.name = expr.getName().getString(scratch).str();
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::SequenceExpr translateSequenceExpr(const swift::SequenceExpr& expr) {
|
||||
SequenceExpr entry{dispatcher_.assignNewLabel(expr)};
|
||||
entry.elements = dispatcher_.fetchRepeatedLabels(expr.getElements());
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::BridgeToObjCExpr translateBridgeToObjCExpr(const swift::BridgeToObjCExpr& expr) {
|
||||
BridgeToObjCExpr entry{dispatcher_.assignNewLabel(expr)};
|
||||
entry.sub_expr = dispatcher_.fetchLabel(expr.getSubExpr());
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::BridgeFromObjCExpr translateBridgeFromObjCExpr(const swift::BridgeFromObjCExpr& expr) {
|
||||
BridgeFromObjCExpr entry{dispatcher_.assignNewLabel(expr)};
|
||||
entry.sub_expr = dispatcher_.fetchLabel(expr.getSubExpr());
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::DotSelfExpr translateDotSelfExpr(const swift::DotSelfExpr& expr) {
|
||||
DotSelfExpr entry{dispatcher_.assignNewLabel(expr)};
|
||||
fillIdentityExpr(expr, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::ErrorExpr translateErrorExpr(const swift::ErrorExpr& expr) {
|
||||
ErrorExpr entry{dispatcher_.assignNewLabel(expr)};
|
||||
return entry;
|
||||
}
|
||||
const swift::UnresolvedMemberExpr& expr);
|
||||
codeql::SequenceExpr translateSequenceExpr(const swift::SequenceExpr& expr);
|
||||
codeql::BridgeToObjCExpr translateBridgeToObjCExpr(const swift::BridgeToObjCExpr& expr);
|
||||
codeql::BridgeFromObjCExpr translateBridgeFromObjCExpr(const swift::BridgeFromObjCExpr& expr);
|
||||
codeql::DotSelfExpr translateDotSelfExpr(const swift::DotSelfExpr& expr);
|
||||
codeql::ErrorExpr translateErrorExpr(const swift::ErrorExpr& expr);
|
||||
|
||||
private:
|
||||
void fillAbstractClosureExpr(const swift::AbstractClosureExpr& expr,
|
||||
codeql::AbstractClosureExpr& entry) {
|
||||
assert(expr.getParameters() && "AbstractClosureExpr has getParameters()");
|
||||
assert(expr.getBody() && "AbstractClosureExpr has getBody()");
|
||||
entry.params = dispatcher_.fetchRepeatedLabels(*expr.getParameters());
|
||||
entry.body = dispatcher_.fetchLabel(expr.getBody());
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
codeql::AbstractClosureExpr& entry);
|
||||
TrapLabel<ArgumentTag> emitArgument(const swift::Argument& arg);
|
||||
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 fillIdentityExpr(const swift::IdentityExpr& expr, codeql::IdentityExpr& entry) {
|
||||
assert(expr.getSubExpr() && "IdentityExpr has getSubExpr()");
|
||||
entry.sub_expr = 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);
|
||||
}
|
||||
|
||||
void emitLookupExpr(const swift::LookupExpr* expr, TrapLabel<LookupExprTag> label) {
|
||||
assert(expr->getBase() && "LookupExpr has getBase()");
|
||||
auto baseLabel = dispatcher_.fetchLabel(expr->getBase());
|
||||
dispatcher_.emit(LookupExprsTrap{label, baseLabel});
|
||||
if (expr->hasDecl()) {
|
||||
auto declLabel = dispatcher_.fetchLabel(expr->getDecl().getDecl());
|
||||
dispatcher_.emit(LookupExprMembersTrap{label, declLabel});
|
||||
}
|
||||
}
|
||||
TrapLabel<ImplicitConversionExprTag> label);
|
||||
void emitExplicitCastExpr(swift::ExplicitCastExpr* expr, TrapLabel<ExplicitCastExprTag> label);
|
||||
void fillIdentityExpr(const swift::IdentityExpr& expr, codeql::IdentityExpr& entry);
|
||||
void emitAnyTryExpr(swift::AnyTryExpr* expr, TrapLabel<AnyTryExprTag> label);
|
||||
void emitApplyExpr(const swift::ApplyExpr* expr, TrapLabel<ApplyExprTag> label);
|
||||
void emitSelfApplyExpr(const swift::SelfApplyExpr* expr, TrapLabel<SelfApplyExprTag> label);
|
||||
void emitLookupExpr(const swift::LookupExpr* expr, TrapLabel<LookupExprTag> label);
|
||||
|
||||
/*
|
||||
* `DirectToStorage`, `DirectToImplementation`, and `DirectToImplementation` must be
|
||||
@@ -660,19 +107,7 @@ class ExprVisitor : public AstVisitorBase<ExprVisitor> {
|
||||
typename Ordinary,
|
||||
typename T,
|
||||
typename Label>
|
||||
void emitAccessorSemantics(T* ast, Label label) {
|
||||
switch (ast->getAccessSemantics()) {
|
||||
case swift::AccessSemantics::DirectToStorage:
|
||||
dispatcher_.emit(DirectToStorage{label});
|
||||
break;
|
||||
case swift::AccessSemantics::DirectToImplementation:
|
||||
dispatcher_.emit(DirectToImplementation{label});
|
||||
break;
|
||||
case swift::AccessSemantics::Ordinary:
|
||||
dispatcher_.emit(Ordinary{label});
|
||||
break;
|
||||
}
|
||||
}
|
||||
void emitAccessorSemantics(T* ast, Label label);
|
||||
};
|
||||
|
||||
} // namespace codeql
|
||||
|
||||
90
swift/extractor/visitors/PatternVisitor.cpp
Normal file
90
swift/extractor/visitors/PatternVisitor.cpp
Normal file
@@ -0,0 +1,90 @@
|
||||
#include "swift/extractor/visitors/PatternVisitor.h"
|
||||
|
||||
namespace codeql {
|
||||
|
||||
void PatternVisitor::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()});
|
||||
}
|
||||
|
||||
void PatternVisitor::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 PatternVisitor::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 PatternVisitor::visitAnyPattern(swift::AnyPattern* pattern) {
|
||||
dispatcher_.emit(AnyPatternsTrap{dispatcher_.assignNewLabel(pattern)});
|
||||
}
|
||||
|
||||
void PatternVisitor::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 PatternVisitor::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 PatternVisitor::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 PatternVisitor::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 PatternVisitor::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 PatternVisitor::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 PatternVisitor::visitBoolPattern(swift::BoolPattern* pattern) {
|
||||
auto label = dispatcher_.assignNewLabel(pattern);
|
||||
dispatcher_.emit(BoolPatternsTrap{label, pattern->getValue()});
|
||||
}
|
||||
|
||||
} // namespace codeql
|
||||
@@ -8,90 +8,16 @@ class PatternVisitor : public AstVisitorBase<PatternVisitor> {
|
||||
public:
|
||||
using AstVisitorBase<PatternVisitor>::AstVisitorBase;
|
||||
|
||||
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()});
|
||||
}
|
||||
|
||||
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()});
|
||||
}
|
||||
void visitNamedPattern(swift::NamedPattern* pattern);
|
||||
void visitTypedPattern(swift::TypedPattern* pattern);
|
||||
void visitTuplePattern(swift::TuplePattern* pattern);
|
||||
void visitAnyPattern(swift::AnyPattern* pattern);
|
||||
void visitBindingPattern(swift::BindingPattern* pattern);
|
||||
void visitEnumElementPattern(swift::EnumElementPattern* pattern);
|
||||
void visitOptionalSomePattern(swift::OptionalSomePattern* pattern);
|
||||
void visitIsPattern(swift::IsPattern* pattern);
|
||||
void visitExprPattern(swift::ExprPattern* pattern);
|
||||
void visitParenPattern(swift::ParenPattern* pattern);
|
||||
void visitBoolPattern(swift::BoolPattern* pattern);
|
||||
};
|
||||
} // namespace codeql
|
||||
|
||||
225
swift/extractor/visitors/StmtVisitor.cpp
Normal file
225
swift/extractor/visitors/StmtVisitor.cpp
Normal file
@@ -0,0 +1,225 @@
|
||||
#include "swift/extractor/visitors/StmtVisitor.h"
|
||||
|
||||
namespace codeql {
|
||||
|
||||
void StmtVisitor::visitLabeledStmt(swift::LabeledStmt* stmt) {
|
||||
auto label = dispatcher_.assignNewLabel(stmt);
|
||||
emitLabeledStmt(stmt, label);
|
||||
}
|
||||
|
||||
void StmtVisitor::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
|
||||
}
|
||||
}
|
||||
|
||||
void StmtVisitor::visitLabeledConditionalStmt(swift::LabeledConditionalStmt* stmt) {
|
||||
auto label = dispatcher_.assignNewLabel(stmt);
|
||||
emitLabeledStmt(stmt, label);
|
||||
emitLabeledConditionalStmt(stmt, label);
|
||||
}
|
||||
|
||||
void StmtVisitor::visitCaseLabelItem(swift::CaseLabelItem* labelItem) {
|
||||
auto label = dispatcher_.assignNewLabel(labelItem);
|
||||
assert(labelItem->getPattern() && "CaseLabelItem has Pattern");
|
||||
dispatcher_.emit(CaseLabelItemsTrap{label, dispatcher_.fetchLabel(labelItem->getPattern())});
|
||||
}
|
||||
|
||||
void StmtVisitor::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 StmtVisitor::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 StmtVisitor::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 StmtVisitor::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 StmtVisitor::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 StmtVisitor::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 StmtVisitor::visitWhileStmt(swift::WhileStmt* stmt) {
|
||||
auto label = dispatcher_.assignNewLabel(stmt);
|
||||
emitLabeledStmt(stmt, label);
|
||||
emitLabeledConditionalStmt(stmt, label);
|
||||
dispatcher_.emit(WhileStmtsTrap{label, dispatcher_.fetchLabel(stmt->getBody())});
|
||||
}
|
||||
|
||||
void StmtVisitor::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 StmtVisitor::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 StmtVisitor::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 StmtVisitor::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 StmtVisitor::visitThrowStmt(swift::ThrowStmt* stmt) {
|
||||
auto label = dispatcher_.assignNewLabel(stmt);
|
||||
auto subExprLabel = dispatcher_.fetchLabel(stmt->getSubExpr());
|
||||
dispatcher_.emit(ThrowStmtsTrap{label, subExprLabel});
|
||||
}
|
||||
|
||||
void StmtVisitor::visitDeferStmt(swift::DeferStmt* stmt) {
|
||||
auto label = dispatcher_.assignNewLabel(stmt);
|
||||
auto bodyLabel = dispatcher_.fetchLabel(stmt->getBodyAsWritten());
|
||||
dispatcher_.emit(DeferStmtsTrap{label, bodyLabel});
|
||||
}
|
||||
|
||||
void StmtVisitor::visitDoStmt(swift::DoStmt* stmt) {
|
||||
auto label = dispatcher_.assignNewLabel(stmt);
|
||||
emitLabeledStmt(stmt, label);
|
||||
auto bodyLabel = dispatcher_.fetchLabel(stmt->getBody());
|
||||
dispatcher_.emit(DoStmtsTrap{label, bodyLabel});
|
||||
}
|
||||
|
||||
void StmtVisitor::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 StmtVisitor::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});
|
||||
}
|
||||
|
||||
void StmtVisitor::visitYieldStmt(swift::YieldStmt* stmt) {
|
||||
auto label = dispatcher_.assignNewLabel(stmt);
|
||||
dispatcher_.emit(YieldStmtsTrap{label});
|
||||
auto i = 0u;
|
||||
for (auto* expr : stmt->getYields()) {
|
||||
auto exprLabel = dispatcher_.fetchLabel(expr);
|
||||
dispatcher_.emit(YieldStmtResultsTrap{label, i++, exprLabel});
|
||||
}
|
||||
}
|
||||
|
||||
void StmtVisitor::emitLabeledStmt(const swift::LabeledStmt* stmt, TrapLabel<LabeledStmtTag> label) {
|
||||
if (stmt->getLabelInfo()) {
|
||||
dispatcher_.emit(LabeledStmtLabelsTrap{label, stmt->getLabelInfo().Name.str().str()});
|
||||
}
|
||||
}
|
||||
|
||||
void StmtVisitor::emitLabeledConditionalStmt(swift::LabeledConditionalStmt* stmt,
|
||||
TrapLabel<LabeledConditionalStmtTag> label) {
|
||||
auto condLabel = dispatcher_.fetchLabel(stmt->getCondPointer());
|
||||
dispatcher_.emit(LabeledConditionalStmtsTrap{label, condLabel});
|
||||
}
|
||||
|
||||
} // namespace codeql
|
||||
@@ -8,226 +8,32 @@ class StmtVisitor : public AstVisitorBase<StmtVisitor> {
|
||||
public:
|
||||
using AstVisitorBase<StmtVisitor>::AstVisitorBase;
|
||||
|
||||
void visitLabeledStmt(swift::LabeledStmt* stmt) {
|
||||
auto label = dispatcher_.assignNewLabel(stmt);
|
||||
emitLabeledStmt(stmt, label);
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
void visitLabeledConditionalStmt(swift::LabeledConditionalStmt* stmt) {
|
||||
auto label = dispatcher_.assignNewLabel(stmt);
|
||||
emitLabeledStmt(stmt, label);
|
||||
emitLabeledConditionalStmt(stmt, label);
|
||||
}
|
||||
|
||||
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});
|
||||
}
|
||||
|
||||
void visitYieldStmt(swift::YieldStmt* stmt) {
|
||||
auto label = dispatcher_.assignNewLabel(stmt);
|
||||
dispatcher_.emit(YieldStmtsTrap{label});
|
||||
auto i = 0u;
|
||||
for(auto* expr : stmt->getYields()) {
|
||||
auto exprLabel = dispatcher_.fetchLabel(expr);
|
||||
dispatcher_.emit(YieldStmtResultsTrap{label, i++, exprLabel});
|
||||
}
|
||||
}
|
||||
void visitLabeledStmt(swift::LabeledStmt* stmt);
|
||||
void visitStmtCondition(swift::StmtCondition* cond);
|
||||
void visitLabeledConditionalStmt(swift::LabeledConditionalStmt* stmt);
|
||||
void visitCaseLabelItem(swift::CaseLabelItem* labelItem);
|
||||
void visitBraceStmt(swift::BraceStmt* stmt);
|
||||
void visitReturnStmt(swift::ReturnStmt* stmt);
|
||||
void visitForEachStmt(swift::ForEachStmt* stmt);
|
||||
void visitIfStmt(swift::IfStmt* stmt);
|
||||
void visitBreakStmt(swift::BreakStmt* stmt);
|
||||
void visitContinueStmt(swift::ContinueStmt* stmt);
|
||||
void visitWhileStmt(swift::WhileStmt* stmt);
|
||||
void visitRepeatWhileStmt(swift::RepeatWhileStmt* stmt);
|
||||
void visitDoCatchStmt(swift::DoCatchStmt* stmt);
|
||||
void visitCaseStmt(swift::CaseStmt* stmt);
|
||||
void visitGuardStmt(swift::GuardStmt* stmt);
|
||||
void visitThrowStmt(swift::ThrowStmt* stmt);
|
||||
void visitDeferStmt(swift::DeferStmt* stmt);
|
||||
void visitDoStmt(swift::DoStmt* stmt);
|
||||
void visitSwitchStmt(swift::SwitchStmt* stmt);
|
||||
void visitFallthroughStmt(swift::FallthroughStmt* stmt);
|
||||
void visitYieldStmt(swift::YieldStmt* stmt);
|
||||
|
||||
private:
|
||||
void emitLabeledStmt(const swift::LabeledStmt* stmt, TrapLabel<LabeledStmtTag> label) {
|
||||
if (stmt->getLabelInfo()) {
|
||||
dispatcher_.emit(LabeledStmtLabelsTrap{label, stmt->getLabelInfo().Name.str().str()});
|
||||
}
|
||||
}
|
||||
|
||||
void emitLabeledStmt(const swift::LabeledStmt* stmt, TrapLabel<LabeledStmtTag> label);
|
||||
void emitLabeledConditionalStmt(swift::LabeledConditionalStmt* stmt,
|
||||
TrapLabel<LabeledConditionalStmtTag> label) {
|
||||
auto condLabel = dispatcher_.fetchLabel(stmt->getCondPointer());
|
||||
dispatcher_.emit(LabeledConditionalStmtsTrap{label, condLabel});
|
||||
}
|
||||
TrapLabel<LabeledConditionalStmtTag> label);
|
||||
};
|
||||
|
||||
} // namespace codeql
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "swift/extractor/SwiftDispatcher.h"
|
||||
#include "swift/extractor/infra/SwiftDispatcher.h"
|
||||
#include "swift/extractor/visitors/DeclVisitor.h"
|
||||
#include "swift/extractor/visitors/ExprVisitor.h"
|
||||
#include "swift/extractor/visitors/StmtVisitor.h"
|
||||
3
swift/extractor/visitors/TypeReprVisitor.cpp
Normal file
3
swift/extractor/visitors/TypeReprVisitor.cpp
Normal file
@@ -0,0 +1,3 @@
|
||||
#include "swift/extractor/visitors/TypeReprVisitor.h"
|
||||
|
||||
namespace codeql {} // namespace codeql
|
||||
235
swift/extractor/visitors/TypeVisitor.cpp
Normal file
235
swift/extractor/visitors/TypeVisitor.cpp
Normal file
@@ -0,0 +1,235 @@
|
||||
#include "swift/extractor/visitors/TypeVisitor.h"
|
||||
namespace codeql {
|
||||
void TypeVisitor::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 TypeVisitor::visitProtocolType(swift::ProtocolType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
dispatcher_.emit(ProtocolTypesTrap{label});
|
||||
emitAnyGenericType(type, label);
|
||||
}
|
||||
|
||||
void TypeVisitor::visitEnumType(swift::EnumType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
dispatcher_.emit(EnumTypesTrap{label});
|
||||
emitAnyGenericType(type, label);
|
||||
}
|
||||
|
||||
void TypeVisitor::visitStructType(swift::StructType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
dispatcher_.emit(StructTypesTrap{label});
|
||||
emitAnyGenericType(type, label);
|
||||
}
|
||||
|
||||
void TypeVisitor::visitClassType(swift::ClassType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
dispatcher_.emit(ClassTypesTrap{label});
|
||||
emitAnyGenericType(type, label);
|
||||
}
|
||||
|
||||
void TypeVisitor::visitFunctionType(swift::FunctionType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
dispatcher_.emit(FunctionTypesTrap{label});
|
||||
emitAnyFunctionType(type, label);
|
||||
}
|
||||
|
||||
void TypeVisitor::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 TypeVisitor::visitBoundGenericEnumType(swift::BoundGenericEnumType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
dispatcher_.emit(BoundGenericEnumTypesTrap{label});
|
||||
emitBoundGenericType(type, label);
|
||||
}
|
||||
|
||||
void TypeVisitor::visitMetatypeType(swift::MetatypeType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
dispatcher_.emit(MetatypeTypesTrap{label});
|
||||
}
|
||||
|
||||
void TypeVisitor::visitExistentialMetatypeType(swift::ExistentialMetatypeType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
dispatcher_.emit(ExistentialMetatypeTypesTrap{label});
|
||||
}
|
||||
|
||||
void TypeVisitor::visitBoundGenericStructType(swift::BoundGenericStructType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
dispatcher_.emit(BoundGenericStructTypesTrap{label});
|
||||
emitBoundGenericType(type, label);
|
||||
}
|
||||
|
||||
void TypeVisitor::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 TypeVisitor::visitBuiltinIntegerLiteralType(swift::BuiltinIntegerLiteralType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
dispatcher_.emit(BuiltinIntegerLiteralTypesTrap{label});
|
||||
}
|
||||
|
||||
void TypeVisitor::visitBuiltinFloatType(swift::BuiltinFloatType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
dispatcher_.emit(BuiltinFloatTypesTrap{label});
|
||||
}
|
||||
|
||||
void TypeVisitor::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 TypeVisitor::visitBoundGenericClassType(swift::BoundGenericClassType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
dispatcher_.emit(BoundGenericClassTypesTrap{label});
|
||||
emitBoundGenericType(type, label);
|
||||
}
|
||||
|
||||
void TypeVisitor::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 TypeVisitor::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 TypeVisitor::visitUnarySyntaxSugarType(swift::UnarySyntaxSugarType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
emitUnarySyntaxSugarType(type, label);
|
||||
}
|
||||
|
||||
void TypeVisitor::visitOptionalType(swift::OptionalType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
dispatcher_.emit(OptionalTypesTrap{label});
|
||||
emitUnarySyntaxSugarType(type, label);
|
||||
}
|
||||
|
||||
void TypeVisitor::visitArraySliceType(swift::ArraySliceType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
dispatcher_.emit(ArraySliceTypesTrap{label});
|
||||
emitUnarySyntaxSugarType(type, label);
|
||||
}
|
||||
|
||||
void TypeVisitor::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 TypeVisitor::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 TypeVisitor::visitGenericTypeParamType(swift::GenericTypeParamType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
dispatcher_.emit(GenericTypeParamTypesTrap{label, type->getName().str().str()});
|
||||
}
|
||||
|
||||
void TypeVisitor::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 TypeVisitor::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 TypeVisitor::visitUnboundGenericType(swift::UnboundGenericType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
dispatcher_.emit(UnboundGenericTypesTrap{label});
|
||||
emitAnyGenericType(type, label);
|
||||
}
|
||||
|
||||
void TypeVisitor::visitBoundGenericType(swift::BoundGenericType* type) {
|
||||
auto label = dispatcher_.assignNewLabel(type);
|
||||
emitBoundGenericType(type, label);
|
||||
}
|
||||
|
||||
void TypeVisitor::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 TypeVisitor::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;
|
||||
}
|
||||
|
||||
if (type->isThrowing()) {
|
||||
dispatcher_.emit(AnyFunctionTypeIsThrowingTrap{label});
|
||||
}
|
||||
|
||||
if (type->isAsync()) {
|
||||
dispatcher_.emit(AnyFunctionTypeIsAsyncTrap{label});
|
||||
}
|
||||
}
|
||||
|
||||
void TypeVisitor::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 TypeVisitor::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
|
||||
@@ -6,236 +6,41 @@ class TypeVisitor : public TypeVisitorBase<TypeVisitor> {
|
||||
public:
|
||||
using TypeVisitorBase<TypeVisitor>::TypeVisitorBase;
|
||||
|
||||
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);
|
||||
}
|
||||
void visit(swift::TypeBase* type);
|
||||
void visitProtocolType(swift::ProtocolType* type);
|
||||
void visitEnumType(swift::EnumType* type);
|
||||
void visitStructType(swift::StructType* type);
|
||||
void visitClassType(swift::ClassType* type);
|
||||
void visitFunctionType(swift::FunctionType* type);
|
||||
void visitTupleType(swift::TupleType* type);
|
||||
void visitBoundGenericEnumType(swift::BoundGenericEnumType* type);
|
||||
void visitMetatypeType(swift::MetatypeType* type);
|
||||
void visitExistentialMetatypeType(swift::ExistentialMetatypeType* type);
|
||||
void visitBoundGenericStructType(swift::BoundGenericStructType* type);
|
||||
void visitTypeAliasType(swift::TypeAliasType* type);
|
||||
void visitBuiltinIntegerLiteralType(swift::BuiltinIntegerLiteralType* type);
|
||||
void visitBuiltinFloatType(swift::BuiltinFloatType* type);
|
||||
void visitBuiltinIntegerType(swift::BuiltinIntegerType* type);
|
||||
void visitBoundGenericClassType(swift::BoundGenericClassType* type);
|
||||
void visitDependentMemberType(swift::DependentMemberType* type);
|
||||
void visitParenType(swift::ParenType* type);
|
||||
void visitUnarySyntaxSugarType(swift::UnarySyntaxSugarType* type);
|
||||
void visitOptionalType(swift::OptionalType* type);
|
||||
void visitArraySliceType(swift::ArraySliceType* type);
|
||||
void visitDictionaryType(swift::DictionaryType* type);
|
||||
void visitGenericFunctionType(swift::GenericFunctionType* type);
|
||||
void visitGenericTypeParamType(swift::GenericTypeParamType* type);
|
||||
void visitLValueType(swift::LValueType* type);
|
||||
void visitPrimaryArchetypeType(swift::PrimaryArchetypeType* type);
|
||||
void visitUnboundGenericType(swift::UnboundGenericType* type);
|
||||
void visitBoundGenericType(swift::BoundGenericType* type);
|
||||
|
||||
private:
|
||||
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;
|
||||
}
|
||||
|
||||
if (type->isThrowing()) {
|
||||
dispatcher_.emit(AnyFunctionTypeIsThrowingTrap{label});
|
||||
}
|
||||
|
||||
if (type->isAsync()) {
|
||||
dispatcher_.emit(AnyFunctionTypeIsAsyncTrap{label});
|
||||
}
|
||||
}
|
||||
|
||||
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)});
|
||||
}
|
||||
}
|
||||
TrapLabel<UnarySyntaxSugarTypeTag> label);
|
||||
void emitAnyFunctionType(const swift::AnyFunctionType* type, TrapLabel<AnyFunctionTypeTag> label);
|
||||
void emitBoundGenericType(swift::BoundGenericType* type, TrapLabel<BoundGenericTypeTag> label);
|
||||
void emitAnyGenericType(swift::AnyGenericType* type, TrapLabel<AnyGenericTypeTag> label);
|
||||
};
|
||||
|
||||
} // namespace codeql
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include <swift/AST/ASTVisitor.h>
|
||||
#include <swift/AST/TypeVisitor.h>
|
||||
|
||||
#include "swift/extractor/SwiftDispatcher.h"
|
||||
#include "swift/extractor/infra/SwiftDispatcher.h"
|
||||
|
||||
namespace codeql {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user