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:
Paolo Tranquilli
2022-06-22 16:44:06 +02:00
parent 7c958dfbb9
commit 22321aa124
21 changed files with 1786 additions and 1508 deletions

View File

@@ -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",
],
)

View File

@@ -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;

View File

@@ -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>

View 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",
],
)

View File

@@ -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 {

View File

@@ -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);

View File

@@ -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",

View 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",
],
)

View 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

View File

@@ -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;

View 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

View File

@@ -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

View 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

View File

@@ -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

View 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

View File

@@ -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

View File

@@ -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"

View File

@@ -0,0 +1,3 @@
#include "swift/extractor/visitors/TypeReprVisitor.h"
namespace codeql {} // namespace codeql

View 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

View File

@@ -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

View File

@@ -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 {