Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 3 additions & 88 deletions swift/codegen/schema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ _includes:
_directories:
decl: Decl$|Context$
pattern: Pattern$
type: Type$
typerepr: TypeRepr$
type: Type(Repr)?$
expr: Expr$
stmt: Stmt$

Expand Down Expand Up @@ -185,6 +184,7 @@ Stmt:

TypeRepr:
_extends: AstNode
type: Type? # type can be absent on unresolved entities

FunctionType:
_extends: AnyFunctionType
Expand Down Expand Up @@ -406,7 +406,6 @@ EnumIsCaseExpr:
_extends: Expr
_children:
sub_expr: Expr
type_repr: TypeRepr
element: EnumElementDecl

ErrorExpr:
Expand Down Expand Up @@ -457,7 +456,7 @@ KeyPathDotExpr:
KeyPathExpr:
_extends: Expr
_children:
parsed_root: Expr?
root: TypeRepr?
parsed_path: Expr?

LazyInitializerExpr:
Expand Down Expand Up @@ -1177,87 +1176,3 @@ FloatLiteralExpr:
IntegerLiteralExpr:
_extends: NumberLiteralExpr
string_value: string

ErrorTypeRepr:
_extends: TypeRepr

AttributedTypeRepr:
_extends: TypeRepr

IdentTypeRepr:
_extends: TypeRepr

ComponentIdentTypeRepr:
_extends: IdentTypeRepr

SimpleIdentTypeRepr:
_extends: ComponentIdentTypeRepr

GenericIdentTypeRepr:
_extends: ComponentIdentTypeRepr

CompoundIdentTypeRepr:
_extends: IdentTypeRepr

FunctionTypeRepr:
_extends: TypeRepr

ArrayTypeRepr:
_extends: TypeRepr

DictionaryTypeRepr:
_extends: TypeRepr

OptionalTypeRepr:
_extends: TypeRepr

ImplicitlyUnwrappedOptionalTypeRepr:
_extends: TypeRepr

TupleTypeRepr:
_extends: TypeRepr

CompositionTypeRepr:
_extends: TypeRepr

MetatypeTypeRepr:
_extends: TypeRepr

ProtocolTypeRepr:
_extends: TypeRepr

OpaqueReturnTypeRepr:
_extends: TypeRepr

NamedOpaqueReturnTypeRepr:
_extends: TypeRepr

ExistentialTypeRepr:
_extends: TypeRepr

PlaceholderTypeRepr:
_extends: TypeRepr

SpecifierTypeRepr:
_extends: TypeRepr

InOutTypeRepr:
_extends: SpecifierTypeRepr

SharedTypeRepr:
_extends: SpecifierTypeRepr

OwnedTypeRepr:
_extends: SpecifierTypeRepr

IsolatedTypeRepr:
_extends: SpecifierTypeRepr

CompileTimeConstTypeRepr:
_extends: SpecifierTypeRepr

FixedTypeRepr:
_extends: TypeRepr

SilBoxTypeRepr:
_extends: TypeRepr
26 changes: 16 additions & 10 deletions swift/extractor/infra/SwiftDispatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ class SwiftDispatcher {
// This method gives a TRAP label for already emitted AST node.
// If the AST node was not emitted yet, then the emission is dispatched to a corresponding
// visitor (see `visit(T *)` methods below).
template <typename E>
TrapLabelOf<E> fetchLabel(E* e) {
template <typename E, typename... Args>
TrapLabelOf<E> fetchLabel(E* e, Args&&... args) {
assert(e && "trying to fetch a label on nullptr, maybe fetchOptionalLabel is to be used?");
// this is required so we avoid any recursive loop: a `fetchLabel` during the visit of `e` might
// end up calling `fetchLabel` on `e` itself, so we want the visit of `e` to call `fetchLabel`
Expand All @@ -73,7 +73,7 @@ class SwiftDispatcher {
return *l;
}
waitingForNewLabel = e;
visit(e);
visit(e, std::forward<Args>(args)...);
// TODO when everything is moved to structured C++ classes, this should be moved to createEntry
if (auto l = store.get(e)) {
if constexpr (!std::is_base_of_v<swift::TypeBase, E>) {
Expand Down Expand Up @@ -168,10 +168,10 @@ class SwiftDispatcher {
// return `std::optional(fetchLabel(arg))` if arg converts to true, otherwise std::nullopt
// universal reference `Arg&&` is used to catch both temporary and non-const references, not
// for perfect forwarding
template <typename Arg>
auto fetchOptionalLabel(Arg&& arg) -> std::optional<decltype(fetchLabel(arg))> {
template <typename Arg, typename... Args>
auto fetchOptionalLabel(Arg&& arg, Args&&... args) -> std::optional<decltype(fetchLabel(arg))> {
if (arg) {
return fetchLabel(arg);
return fetchLabel(arg, std::forward<Args>(args)...);
}
return std::nullopt;
}
Expand Down Expand Up @@ -263,9 +263,15 @@ class SwiftDispatcher {

template <typename Tag, typename T, typename... Ts>
bool fetchLabelFromUnionCase(const llvm::PointerUnion<Ts...> u, TrapLabel<Tag>& output) {
if (auto e = u.template dyn_cast<T>()) {
output = fetchLabel(e);
return true;
// we rely on the fact that when we extract `ASTNode` instances (which only happens
// on `BraceStmt` elements), we cannot encounter a standalone `TypeRepr` there, so we skip
// this case; extracting `TypeRepr`s here would be problematic as we would not be able to
// provide the corresponding type
if constexpr (!std::is_same_v<T, swift::TypeRepr*>) {
if (auto e = u.template dyn_cast<T>()) {
output = fetchLabel(e);
return true;
}
}
return false;
}
Expand Down Expand Up @@ -294,7 +300,7 @@ class SwiftDispatcher {
virtual void visit(swift::CaseLabelItem* item) = 0;
virtual void visit(swift::Expr* expr) = 0;
virtual void visit(swift::Pattern* pattern) = 0;
virtual void visit(swift::TypeRepr* type) = 0;
virtual void visit(swift::TypeRepr* typeRepr, swift::Type type) = 0;
virtual void visit(swift::TypeBase* type) = 0;

const swift::SourceManager& sourceManager;
Expand Down
4 changes: 0 additions & 4 deletions swift/extractor/infra/SwiftTagTraits.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ using SILBlockStorageTypeTag = SilBlockStorageTypeTag;
using SILBoxTypeTag = SilBoxTypeTag;
using SILFunctionTypeTag = SilFunctionTypeTag;
using SILTokenTypeTag = SilTokenTypeTag;
using SILBoxTypeReprTag = SilBoxTypeReprTag;

#define MAP_TYPE_TO_TAG(TYPE, TAG) \
template <> \
Expand Down Expand Up @@ -60,9 +59,6 @@ MAP_TAG(Pattern);
#include <swift/AST/PatternNodes.def>

MAP_TAG(TypeRepr);
#define ABSTRACT_TYPEREPR(CLASS, PARENT) MAP_SUBTAG(CLASS##TypeRepr, PARENT)
#define TYPEREPR(CLASS, PARENT) ABSTRACT_TYPEREPR(CLASS, PARENT)
#include <swift/AST/TypeReprNodes.def>

MAP_TYPE_TO_TAG(TypeBase, TypeTag);
#define ABSTRACT_TYPE(CLASS, PARENT) MAP_SUBTAG(CLASS##Type, PARENT)
Expand Down
2 changes: 1 addition & 1 deletion swift/extractor/trap/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
load("//swift:rules.bzl", "swift_cc_library")

_dirs = ("", "decl/", "expr/", "pattern/", "stmt/", "type/", "typerepr/")
_dirs = ("", "decl/", "expr/", "pattern/", "stmt/", "type/")

genrule(
name = "cppgen",
Expand Down
18 changes: 12 additions & 6 deletions swift/extractor/visitors/ExprVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,9 +188,8 @@ void ExprVisitor::visitEnumIsCaseExpr(swift::EnumIsCaseExpr* expr) {
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});
dispatcher_.emit(EnumIsCaseExprsTrap{label, subExpr, enumElement});
}

void ExprVisitor::visitMakeTemporarilyEscapableExpr(swift::MakeTemporarilyEscapableExpr* expr) {
Expand Down Expand Up @@ -288,7 +287,9 @@ void ExprVisitor::visitErasureExpr(swift::ErasureExpr* expr) {

codeql::TypeExpr ExprVisitor::translateTypeExpr(const swift::TypeExpr& expr) {
TypeExpr entry{dispatcher_.assignNewLabel(expr)};
entry.type_repr = dispatcher_.fetchOptionalLabel(expr.getTypeRepr());
if (expr.getTypeRepr() && expr.getInstanceType()) {
entry.type_repr = dispatcher_.fetchLabel(expr.getTypeRepr(), expr.getInstanceType());
}
return entry;
}

Expand Down Expand Up @@ -478,9 +479,14 @@ void ExprVisitor::visitKeyPathExpr(swift::KeyPathExpr* expr) {
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});
// TODO maybe move this logic to QL?
if (auto rootTypeRepr = expr->getRootType()) {
auto keyPathType = expr->getType()->getAs<swift::BoundGenericClassType>();
assert(keyPathType && "KeyPathExpr must have BoundGenericClassType");
auto keyPathTypeArgs = keyPathType->getGenericArgs();
assert(keyPathTypeArgs.size() != 0 && "KeyPathExpr type must have generic args");
auto rootLabel = dispatcher_.fetchLabel(rootTypeRepr, keyPathTypeArgs[0]);
dispatcher_.emit(KeyPathExprRootsTrap{label, rootLabel});
}
}
}
Expand Down
7 changes: 4 additions & 3 deletions swift/extractor/visitors/PatternVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ void PatternVisitor::visitTypedPattern(swift::TypedPattern* 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())});
dispatcher_.emit(TypedPatternTypeReprsTrap{
label, dispatcher_.fetchLabel(pattern->getTypeRepr(), pattern->getType())});
}
}

Expand Down Expand Up @@ -63,7 +63,8 @@ void PatternVisitor::visitIsPattern(swift::IsPattern* pattern) {
dispatcher_.emit(IsPatternsTrap{label});

if (auto typeRepr = pattern->getCastTypeRepr()) {
dispatcher_.emit(IsPatternCastTypeReprsTrap{label, dispatcher_.fetchLabel(typeRepr)});
dispatcher_.emit(IsPatternCastTypeReprsTrap{
label, dispatcher_.fetchLabel(typeRepr, pattern->getCastType())});
}
if (auto subPattern = pattern->getSubPattern()) {
dispatcher_.emit(IsPatternSubPatternsTrap{label, dispatcher_.fetchLabel(subPattern)});
Expand Down
6 changes: 3 additions & 3 deletions swift/extractor/visitors/SwiftVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
#include "swift/extractor/visitors/ExprVisitor.h"
#include "swift/extractor/visitors/StmtVisitor.h"
#include "swift/extractor/visitors/TypeVisitor.h"
#include "swift/extractor/visitors/TypeReprVisitor.h"
#include "swift/extractor/visitors/PatternVisitor.h"

namespace codeql {
Expand All @@ -32,13 +31,14 @@ class SwiftVisitor : private SwiftDispatcher {
void visit(swift::CaseLabelItem* item) override { stmtVisitor.visitCaseLabelItem(item); }
void visit(swift::Expr* expr) override { exprVisitor.visit(expr); }
void visit(swift::Pattern* pattern) override { patternVisitor.visit(pattern); }
void visit(swift::TypeRepr* type) override { typeReprVisitor.visit(type); }
void visit(swift::TypeBase* type) override { typeVisitor.visit(type); }
void visit(swift::TypeRepr* typeRepr, swift::Type type) override {
emit(typeVisitor.translateTypeRepr(*typeRepr, type));
}

DeclVisitor declVisitor{*this};
ExprVisitor exprVisitor{*this};
StmtVisitor stmtVisitor{*this};
TypeReprVisitor typeReprVisitor{*this};
TypeVisitor typeVisitor{*this};
PatternVisitor patternVisitor{*this};
};
Expand Down
3 changes: 0 additions & 3 deletions swift/extractor/visitors/TypeReprVisitor.cpp

This file was deleted.

13 changes: 0 additions & 13 deletions swift/extractor/visitors/TypeReprVisitor.h

This file was deleted.

6 changes: 6 additions & 0 deletions swift/extractor/visitors/TypeVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ void TypeVisitor::visit(swift::TypeBase* type) {
dispatcher_.emit(TypesTrap{label, type->getString(), canonicalLabel});
}

codeql::TypeRepr TypeVisitor::translateTypeRepr(const swift::TypeRepr& typeRepr, swift::Type type) {
auto entry = dispatcher_.createEntry(typeRepr);
entry.type = dispatcher_.fetchOptionalLabel(type);
return entry;
}

void TypeVisitor::visitProtocolType(swift::ProtocolType* type) {
auto label = dispatcher_.assignNewLabel(type);
dispatcher_.emit(ProtocolTypesTrap{label});
Expand Down
2 changes: 2 additions & 0 deletions swift/extractor/visitors/TypeVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ class TypeVisitor : public TypeVisitorBase<TypeVisitor> {
using TypeVisitorBase<TypeVisitor>::TypeVisitorBase;

void visit(swift::TypeBase* type);
codeql::TypeRepr translateTypeRepr(const swift::TypeRepr& typeRepr, swift::Type type);

void visitProtocolType(swift::ProtocolType* type);
void visitEnumType(swift::EnumType* type);
void visitStructType(swift::StructType* type);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ module CfgScope {
private class KeyPathScope extends Range_ instanceof KeyPathExpr {
AstControlFlowTree tree;

KeyPathScope() { tree.getAst() = this.getParsedRoot().getFullyConverted() }
KeyPathScope() { tree.getAst() = this }

final override predicate entry(ControlFlowElement first) { first(tree, first) }

Expand Down Expand Up @@ -836,9 +836,6 @@ module Patterns {
// Note: `getSubPattern` only has a result if the `is` pattern is of the form `pattern as type`.
i = 0 and
result.asAstNode() = ast.getSubPattern().getFullyUnresolved()
or
i = 1 and
result.asAstNode() = ast.getCastTypeRepr()
}
}

Expand Down Expand Up @@ -1604,8 +1601,14 @@ module Exprs {

final override ControlFlowElement getChildElement(int i) {
result.asAstNode() = ast.getSubExpr().getFullyConverted() and i = 0
or
result.asAstNode() = ast.getTypeRepr().getFullyUnresolved() and i = 1
}
}

private class IsTree extends AstStandardPostOrderTree {
override IsExpr ast;

final override ControlFlowElement getChildElement(int i) {
result.asAstNode() = ast.getSubExpr().getFullyConverted() and i = 0
}
}

Expand Down
Loading