Skip to content

Commit 033b239

Browse files
committed
Swift: collapse TypeRepr hierarchy
Now `TypeRepr` is a final class in the AST, which is more or less just a type with a location in code. As the frontend does not provide a direct way to get a type from a type representation, this information must be provided when fetching the label of a type repr. This meant: * removing the type repr field from `EnumIsCaseExpr`: this is a virtual AST node introduced in place of some kinds of `IsEpxr`. The type repr is still available from the `ConditionalCheckedCastExpr` wrapped by this virtual node, and we will rebuild the original `IsExpr` with the IPA layer. * some logic to get the type of keypath roots has been added to `KeyPathExpr`. This was done to keep the `TypeRepr` to `Type` relation total in the DB, but goes against the design of a dumb extractor. The logic could be moved to QL in the future * in the control flow library, `TypeRepr` children are now ignored. As far as I can tell, there is no runtime evaluation going on in `TypeRepr`s, so it does not make much sense to have control flow through them.
1 parent 70838fe commit 033b239

File tree

98 files changed

+646
-760
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

98 files changed

+646
-760
lines changed

swift/codegen/schema.yml

Lines changed: 3 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ _includes:
77
_directories:
88
decl: Decl$|Context$
99
pattern: Pattern$
10-
type: Type$
11-
typerepr: TypeRepr$
10+
type: Type(Repr)?$
1211
expr: Expr$
1312
stmt: Stmt$
1413

@@ -181,6 +180,7 @@ Stmt:
181180

182181
TypeRepr:
183182
_extends: AstNode
183+
type: Type
184184

185185
FunctionType:
186186
_extends: AnyFunctionType
@@ -391,7 +391,6 @@ EnumIsCaseExpr:
391391
_extends: Expr
392392
_children:
393393
sub_expr: Expr
394-
type_repr: TypeRepr
395394
element: EnumElementDecl
396395

397396
ErrorExpr:
@@ -442,7 +441,7 @@ KeyPathDotExpr:
442441
KeyPathExpr:
443442
_extends: Expr
444443
_children:
445-
parsed_root: Expr?
444+
root: TypeRepr?
446445
parsed_path: Expr?
447446

448447
LazyInitializerExpr:
@@ -1162,87 +1161,3 @@ FloatLiteralExpr:
11621161
IntegerLiteralExpr:
11631162
_extends: NumberLiteralExpr
11641163
string_value: string
1165-
1166-
ErrorTypeRepr:
1167-
_extends: TypeRepr
1168-
1169-
AttributedTypeRepr:
1170-
_extends: TypeRepr
1171-
1172-
IdentTypeRepr:
1173-
_extends: TypeRepr
1174-
1175-
ComponentIdentTypeRepr:
1176-
_extends: IdentTypeRepr
1177-
1178-
SimpleIdentTypeRepr:
1179-
_extends: ComponentIdentTypeRepr
1180-
1181-
GenericIdentTypeRepr:
1182-
_extends: ComponentIdentTypeRepr
1183-
1184-
CompoundIdentTypeRepr:
1185-
_extends: IdentTypeRepr
1186-
1187-
FunctionTypeRepr:
1188-
_extends: TypeRepr
1189-
1190-
ArrayTypeRepr:
1191-
_extends: TypeRepr
1192-
1193-
DictionaryTypeRepr:
1194-
_extends: TypeRepr
1195-
1196-
OptionalTypeRepr:
1197-
_extends: TypeRepr
1198-
1199-
ImplicitlyUnwrappedOptionalTypeRepr:
1200-
_extends: TypeRepr
1201-
1202-
TupleTypeRepr:
1203-
_extends: TypeRepr
1204-
1205-
CompositionTypeRepr:
1206-
_extends: TypeRepr
1207-
1208-
MetatypeTypeRepr:
1209-
_extends: TypeRepr
1210-
1211-
ProtocolTypeRepr:
1212-
_extends: TypeRepr
1213-
1214-
OpaqueReturnTypeRepr:
1215-
_extends: TypeRepr
1216-
1217-
NamedOpaqueReturnTypeRepr:
1218-
_extends: TypeRepr
1219-
1220-
ExistentialTypeRepr:
1221-
_extends: TypeRepr
1222-
1223-
PlaceholderTypeRepr:
1224-
_extends: TypeRepr
1225-
1226-
SpecifierTypeRepr:
1227-
_extends: TypeRepr
1228-
1229-
InOutTypeRepr:
1230-
_extends: SpecifierTypeRepr
1231-
1232-
SharedTypeRepr:
1233-
_extends: SpecifierTypeRepr
1234-
1235-
OwnedTypeRepr:
1236-
_extends: SpecifierTypeRepr
1237-
1238-
IsolatedTypeRepr:
1239-
_extends: SpecifierTypeRepr
1240-
1241-
CompileTimeConstTypeRepr:
1242-
_extends: SpecifierTypeRepr
1243-
1244-
FixedTypeRepr:
1245-
_extends: TypeRepr
1246-
1247-
SilBoxTypeRepr:
1248-
_extends: TypeRepr

swift/extractor/infra/SwiftDispatcher.h

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ class SwiftDispatcher {
6464
// This method gives a TRAP label for already emitted AST node.
6565
// If the AST node was not emitted yet, then the emission is dispatched to a corresponding
6666
// visitor (see `visit(T *)` methods below).
67-
template <typename E>
68-
TrapLabelOf<E> fetchLabel(E* e) {
67+
template <typename E, typename... Args>
68+
TrapLabelOf<E> fetchLabel(E* e, Args&&... args) {
6969
assert(e && "trying to fetch a label on nullptr, maybe fetchOptionalLabel is to be used?");
7070
// this is required so we avoid any recursive loop: a `fetchLabel` during the visit of `e` might
7171
// end up calling `fetchLabel` on `e` itself, so we want the visit of `e` to call `fetchLabel`
@@ -76,7 +76,7 @@ class SwiftDispatcher {
7676
return *l;
7777
}
7878
waitingForNewLabel = e;
79-
visit(e);
79+
visit(e, std::forward<Args>(args)...);
8080
if (auto l = store.get(e)) {
8181
if constexpr (!std::is_base_of_v<swift::TypeBase, E>) {
8282
attachLocation(e, *l);
@@ -158,10 +158,10 @@ class SwiftDispatcher {
158158
// return `std::optional(fetchLabel(arg))` if arg converts to true, otherwise std::nullopt
159159
// universal reference `Arg&&` is used to catch both temporary and non-const references, not
160160
// for perfect forwarding
161-
template <typename Arg>
162-
auto fetchOptionalLabel(Arg&& arg) -> std::optional<decltype(fetchLabel(arg))> {
161+
template <typename Arg, typename... Args>
162+
auto fetchOptionalLabel(Arg&& arg, Args&&... args) -> std::optional<decltype(fetchLabel(arg))> {
163163
if (arg) {
164-
return fetchLabel(arg);
164+
return fetchLabel(arg, std::forward<Args>(args)...);
165165
}
166166
return std::nullopt;
167167
}
@@ -251,9 +251,11 @@ class SwiftDispatcher {
251251

252252
template <typename Tag, typename T, typename... Ts>
253253
bool fetchLabelFromUnionCase(const llvm::PointerUnion<Ts...> u, TrapLabel<Tag>& output) {
254-
if (auto e = u.template dyn_cast<T>()) {
255-
output = fetchLabel(e);
256-
return true;
254+
if constexpr (!std::is_same_v<T, swift::TypeRepr*>) {
255+
if (auto e = u.template dyn_cast<T>()) {
256+
output = fetchLabel(e);
257+
return true;
258+
}
257259
}
258260
return false;
259261
}
@@ -279,7 +281,7 @@ class SwiftDispatcher {
279281
virtual void visit(swift::CaseLabelItem* item) = 0;
280282
virtual void visit(swift::Expr* expr) = 0;
281283
virtual void visit(swift::Pattern* pattern) = 0;
282-
virtual void visit(swift::TypeRepr* type) = 0;
284+
virtual void visit(swift::TypeRepr* typeRepr, swift::Type type) = 0;
283285
virtual void visit(swift::TypeBase* type) = 0;
284286

285287
const swift::SourceManager& sourceManager;

swift/extractor/infra/SwiftTagTraits.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ using SILBlockStorageTypeTag = SilBlockStorageTypeTag;
1414
using SILBoxTypeTag = SilBoxTypeTag;
1515
using SILFunctionTypeTag = SilFunctionTypeTag;
1616
using SILTokenTypeTag = SilTokenTypeTag;
17-
using SILBoxTypeReprTag = SilBoxTypeReprTag;
1817

1918
#define MAP_TYPE_TO_TAG(TYPE, TAG) \
2019
template <> \
@@ -57,9 +56,6 @@ MAP_TAG(Pattern);
5756
#include <swift/AST/PatternNodes.def>
5857

5958
MAP_TAG(TypeRepr);
60-
#define ABSTRACT_TYPEREPR(CLASS, PARENT) MAP_SUBTAG(CLASS##TypeRepr, PARENT)
61-
#define TYPEREPR(CLASS, PARENT) ABSTRACT_TYPEREPR(CLASS, PARENT)
62-
#include <swift/AST/TypeReprNodes.def>
6359

6460
MAP_TYPE_TO_TAG(TypeBase, TypeTag);
6561
#define ABSTRACT_TYPE(CLASS, PARENT) MAP_SUBTAG(CLASS##Type, PARENT)

swift/extractor/trap/BUILD.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
load("//swift:rules.bzl", "swift_cc_library")
22

3-
_dirs = ("", "decl/", "expr/", "pattern/", "stmt/", "type/", "typerepr/")
3+
_dirs = ("", "decl/", "expr/", "pattern/", "stmt/", "type/")
44

55
genrule(
66
name = "cppgen",

swift/extractor/visitors/ExprVisitor.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -188,9 +188,8 @@ void ExprVisitor::visitEnumIsCaseExpr(swift::EnumIsCaseExpr* expr) {
188188
assert(expr->getCaseTypeRepr() && "EnumIsCaseExpr has CaseTypeRepr");
189189
assert(expr->getEnumElement() && "EnumIsCaseExpr has EnumElement");
190190
auto subExpr = dispatcher_.fetchLabel(expr->getSubExpr());
191-
auto typeRepr = dispatcher_.fetchLabel(expr->getCaseTypeRepr());
192191
auto enumElement = dispatcher_.fetchLabel(expr->getEnumElement());
193-
dispatcher_.emit(EnumIsCaseExprsTrap{label, subExpr, typeRepr, enumElement});
192+
dispatcher_.emit(EnumIsCaseExprsTrap{label, subExpr, enumElement});
194193
}
195194

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

289288
codeql::TypeExpr ExprVisitor::translateTypeExpr(const swift::TypeExpr& expr) {
290289
TypeExpr entry{dispatcher_.assignNewLabel(expr)};
291-
entry.type_repr = dispatcher_.fetchOptionalLabel(expr.getTypeRepr());
290+
if (expr.getTypeRepr() && expr.getInstanceType()) {
291+
entry.type_repr = dispatcher_.fetchLabel(expr.getTypeRepr(), expr.getInstanceType());
292+
}
292293
return entry;
293294
}
294295

@@ -478,9 +479,14 @@ void ExprVisitor::visitKeyPathExpr(swift::KeyPathExpr* expr) {
478479
auto pathLabel = dispatcher_.fetchLabel(path);
479480
dispatcher_.emit(KeyPathExprParsedPathsTrap{label, pathLabel});
480481
}
481-
if (auto root = expr->getParsedRoot()) {
482-
auto rootLabel = dispatcher_.fetchLabel(root);
483-
dispatcher_.emit(KeyPathExprParsedRootsTrap{label, rootLabel});
482+
// TODO maybe move this logic to QL?
483+
if (auto rootTypeRepr = expr->getRootType()) {
484+
auto keyPathType = expr->getType()->getAs<swift::BoundGenericClassType>();
485+
assert(keyPathType && "KeyPathExpr must have BoundGenericClassType");
486+
auto keyPathTypeArgs = keyPathType->getGenericArgs();
487+
assert(keyPathTypeArgs.size() != 0 && "KeyPathExpr type must have generic args");
488+
auto rootLabel = dispatcher_.fetchLabel(rootTypeRepr, keyPathTypeArgs[0]);
489+
dispatcher_.emit(KeyPathExprRootsTrap{label, rootLabel});
484490
}
485491
}
486492
}

swift/extractor/visitors/PatternVisitor.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ void PatternVisitor::visitTypedPattern(swift::TypedPattern* pattern) {
1818
assert(pattern->getSubPattern() && "expect TypedPattern to have a SubPattern");
1919
dispatcher_.emit(TypedPatternsTrap{label, dispatcher_.fetchLabel(pattern->getSubPattern())});
2020
if (auto typeRepr = pattern->getTypeRepr()) {
21-
dispatcher_.emit(
22-
TypedPatternTypeReprsTrap{label, dispatcher_.fetchLabel(pattern->getTypeRepr())});
21+
dispatcher_.emit(TypedPatternTypeReprsTrap{
22+
label, dispatcher_.fetchLabel(pattern->getTypeRepr(), pattern->getType())});
2323
}
2424
}
2525

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

6565
if (auto typeRepr = pattern->getCastTypeRepr()) {
66-
dispatcher_.emit(IsPatternCastTypeReprsTrap{label, dispatcher_.fetchLabel(typeRepr)});
66+
dispatcher_.emit(IsPatternCastTypeReprsTrap{
67+
label, dispatcher_.fetchLabel(typeRepr, pattern->getCastType())});
6768
}
6869
if (auto subPattern = pattern->getSubPattern()) {
6970
dispatcher_.emit(IsPatternSubPatternsTrap{label, dispatcher_.fetchLabel(subPattern)});

swift/extractor/visitors/SwiftVisitor.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#include "swift/extractor/visitors/ExprVisitor.h"
66
#include "swift/extractor/visitors/StmtVisitor.h"
77
#include "swift/extractor/visitors/TypeVisitor.h"
8-
#include "swift/extractor/visitors/TypeReprVisitor.h"
98
#include "swift/extractor/visitors/PatternVisitor.h"
109

1110
namespace codeql {
@@ -26,13 +25,14 @@ class SwiftVisitor : private SwiftDispatcher {
2625
void visit(swift::CaseLabelItem* item) override { stmtVisitor.visitCaseLabelItem(item); }
2726
void visit(swift::Expr* expr) override { exprVisitor.visit(expr); }
2827
void visit(swift::Pattern* pattern) override { patternVisitor.visit(pattern); }
29-
void visit(swift::TypeRepr* type) override { typeReprVisitor.visit(type); }
3028
void visit(swift::TypeBase* type) override { typeVisitor.visit(type); }
29+
void visit(swift::TypeRepr* typeRepr, swift::Type type) override {
30+
typeVisitor.visit(*typeRepr, type);
31+
}
3132

3233
DeclVisitor declVisitor{*this};
3334
ExprVisitor exprVisitor{*this};
3435
StmtVisitor stmtVisitor{*this};
35-
TypeReprVisitor typeReprVisitor{*this};
3636
TypeVisitor typeVisitor{*this};
3737
PatternVisitor patternVisitor{*this};
3838
};

swift/extractor/visitors/TypeReprVisitor.cpp

Lines changed: 0 additions & 3 deletions
This file was deleted.

swift/extractor/visitors/TypeReprVisitor.h

Lines changed: 0 additions & 13 deletions
This file was deleted.

swift/extractor/visitors/TypeVisitor.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ void TypeVisitor::visit(swift::TypeBase* type) {
88
dispatcher_.emit(TypesTrap{label, type->getString(), canonicalLabel});
99
}
1010

11+
void TypeVisitor::visit(const swift::TypeRepr& typeRepr, swift::Type type) {
12+
auto entry = dispatcher_.createEntry(typeRepr);
13+
entry.type = dispatcher_.fetchLabel(type);
14+
dispatcher_.emit(entry);
15+
}
16+
1117
void TypeVisitor::visitProtocolType(swift::ProtocolType* type) {
1218
auto label = dispatcher_.assignNewLabel(type);
1319
dispatcher_.emit(ProtocolTypesTrap{label});

0 commit comments

Comments
 (0)