Skip to content

Commit cf5f1e5

Browse files
committed
Swift: Extract new entities.
1 parent cdb081e commit cf5f1e5

File tree

2 files changed

+102
-9
lines changed

2 files changed

+102
-9
lines changed

swift/extractor/visitors/DeclVisitor.h

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,39 @@ class DeclVisitor : public AstVisitorBase<DeclVisitor> {
157157
emitTypeDecl(decl, label);
158158
}
159159

160+
void visitAccessorDecl(swift::AccessorDecl* decl) {
161+
auto label = dispatcher_.assignNewLabel(decl);
162+
dispatcher_.emit(AccessorDeclsTrap{label});
163+
switch (decl->getAccessorKind()) {
164+
case swift::AccessorKind::Get:
165+
dispatcher_.emit(AccessorDeclIsGetterTrap{label});
166+
break;
167+
case swift::AccessorKind::Set:
168+
dispatcher_.emit(AccessorDeclIsSetterTrap{label});
169+
break;
170+
case swift::AccessorKind::WillSet:
171+
dispatcher_.emit(AccessorDeclIsWillSetTrap{label});
172+
break;
173+
case swift::AccessorKind::DidSet:
174+
dispatcher_.emit(AccessorDeclIsDidSetTrap{label});
175+
break;
176+
}
177+
emitAccessorDecl(decl, label);
178+
}
179+
180+
void visitSubscriptDecl(swift::SubscriptDecl* decl) {
181+
auto label = dispatcher_.assignNewLabel(decl);
182+
auto elementTypeLabel = dispatcher_.fetchLabel(decl->getElementInterfaceType());
183+
dispatcher_.emit(SubscriptDeclsTrap{label, elementTypeLabel});
184+
if (auto indices = decl->getIndices()) {
185+
for (auto i = 0u; i < indices->size(); ++i) {
186+
dispatcher_.emit(
187+
SubscriptDeclParamsTrap{label, i, dispatcher_.fetchLabel(indices->get(i))});
188+
}
189+
}
190+
emitAbstractStorageDecl(decl, label);
191+
}
192+
160193
private:
161194
void emitConstructorDecl(swift::ConstructorDecl* decl, TrapLabel<ConstructorDeclTag> label) {
162195
emitAbstractFunctionDecl(decl, label);
@@ -168,9 +201,9 @@ class DeclVisitor : public AstVisitorBase<DeclVisitor> {
168201

169202
void emitAbstractFunctionDecl(swift::AbstractFunctionDecl* decl,
170203
TrapLabel<AbstractFunctionDeclTag> label) {
171-
assert(decl->hasName() && "Expect functions to have name");
172204
assert(decl->hasParameterList() && "Expect functions to have a parameter list");
173-
auto name = decl->getName().isSpecial() ? "(unnamed function decl)" : decl->getNameStr().str();
205+
auto name = !decl->hasName() || decl->getName().isSpecial() ? "(unnamed function decl)"
206+
: decl->getNameStr().str();
174207
dispatcher_.emit(AbstractFunctionDeclsTrap{label, name});
175208
if (auto body = decl->getBody()) {
176209
dispatcher_.emit(AbstractFunctionDeclBodiesTrap{label, dispatcher_.fetchLabel(body)});
@@ -226,7 +259,7 @@ class DeclVisitor : public AstVisitorBase<DeclVisitor> {
226259
VarDeclAttachedPropertyWrapperTypesTrap{label, dispatcher_.fetchLabel(propertyType)});
227260
}
228261
}
229-
emitValueDecl(decl, label);
262+
emitAbstractStorageDecl(decl, label);
230263
}
231264

232265
void emitNominalTypeDecl(swift::NominalTypeDecl* decl, TrapLabel<NominalTypeDeclTag> label) {
@@ -251,6 +284,20 @@ class DeclVisitor : public AstVisitorBase<DeclVisitor> {
251284
assert(decl->getInterfaceType() && "Expect ValueDecl to have InterfaceType");
252285
dispatcher_.emit(ValueDeclsTrap{label, dispatcher_.fetchLabel(decl->getInterfaceType())});
253286
}
287+
288+
void emitAccessorDecl(swift::AccessorDecl* decl, TrapLabel<AccessorDeclTag> label) {
289+
emitAbstractFunctionDecl(decl, label);
290+
}
291+
292+
void emitAbstractStorageDecl(const swift::AbstractStorageDecl* decl,
293+
TrapLabel<AbstractStorageDeclTag> label) {
294+
auto i = 0u;
295+
for (auto acc : decl->getAllAccessors()) {
296+
dispatcher_.emit(
297+
AbstractStorageDeclAccessorDeclsTrap{label, i++, dispatcher_.fetchLabel(acc)});
298+
}
299+
emitValueDecl(decl, label);
300+
}
254301
};
255302

256303
} // namespace codeql

swift/extractor/visitors/ExprVisitor.h

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ class ExprVisitor : public AstVisitorBase<ExprVisitor> {
8585
void visitDeclRefExpr(swift::DeclRefExpr* expr) {
8686
auto label = dispatcher_.assignNewLabel(expr);
8787
dispatcher_.emit(DeclRefExprsTrap{label, dispatcher_.fetchLabel(expr->getDecl())});
88+
emitAccessorSemantics<DeclRefExprHasDirectToStorageSemanticsTrap,
89+
DeclRefExprHasDirectToImplementationSemanticsTrap,
90+
DeclRefExprHasOrdinarySemanticsTrap>(expr, label);
8891
auto i = 0u;
8992
for (auto t : expr->getDeclRef().getSubstitutions().getReplacementTypes()) {
9093
dispatcher_.emit(DeclRefExprReplacementTypesTrap{label, i++, dispatcher_.fetchLabel(t)});
@@ -398,16 +401,24 @@ class ExprVisitor : public AstVisitorBase<ExprVisitor> {
398401
emitExplicitCastExpr(expr, label);
399402
}
400403

404+
void visitLookupExpr(swift::LookupExpr* expr) {
405+
auto label = dispatcher_.assignNewLabel(expr);
406+
emitLookupExpr(expr, label);
407+
}
408+
401409
void visitSubscriptExpr(swift::SubscriptExpr* expr) {
402410
auto label = dispatcher_.assignNewLabel(expr);
403-
assert(expr->getBase() && "SubscriptExpr has getBase()");
404-
auto baseLabel = dispatcher_.fetchLabel(expr->getBase());
405-
dispatcher_.emit(SubscriptExprsTrap{label, baseLabel});
411+
dispatcher_.emit(SubscriptExprsTrap{label});
412+
413+
emitAccessorSemantics<SubscriptExprHasDirectToStorageSemanticsTrap,
414+
SubscriptExprHasDirectToImplementationSemanticsTrap,
415+
SubscriptExprHasOrdinarySemanticsTrap>(expr, label);
406416

407417
auto i = 0u;
408418
for (const auto& arg : *expr->getArgs()) {
409419
dispatcher_.emit(SubscriptExprArgumentsTrap{label, i++, emitArgument(arg)});
410420
}
421+
emitLookupExpr(expr, label);
411422
}
412423

413424
void visitDictionaryExpr(swift::DictionaryExpr* expr) {
@@ -434,10 +445,13 @@ class ExprVisitor : public AstVisitorBase<ExprVisitor> {
434445

435446
void visitMemberRefExpr(swift::MemberRefExpr* expr) {
436447
auto label = dispatcher_.assignNewLabel(expr);
437-
assert(expr->getBase() && "MemberRefExpr has getBase()");
448+
dispatcher_.emit(MemberRefExprsTrap{label});
438449

439-
auto baseLabel = dispatcher_.fetchLabel(expr->getBase());
440-
dispatcher_.emit(MemberRefExprsTrap{label, baseLabel});
450+
emitAccessorSemantics<MemberRefExprHasDirectToStorageSemanticsTrap,
451+
MemberRefExprHasDirectToImplementationSemanticsTrap,
452+
MemberRefExprHasOrdinarySemanticsTrap>(expr, label);
453+
454+
emitLookupExpr(expr, label);
441455
}
442456

443457
void visitDerivedToBaseExpr(swift::DerivedToBaseExpr* expr) {
@@ -542,6 +556,38 @@ class ExprVisitor : public AstVisitorBase<ExprVisitor> {
542556
dispatcher_.emit(SelfApplyExprsTrap{label, baseLabel});
543557
emitApplyExpr(expr, label);
544558
}
559+
560+
void emitLookupExpr(const swift::LookupExpr* expr, TrapLabel<LookupExprTag> label) {
561+
assert(expr->getBase() && "LookupExpr has getBase()");
562+
auto baseLabel = dispatcher_.fetchLabel(expr->getBase());
563+
assert(expr->hasDecl() && "LookupExpr has decl");
564+
auto declLabel = dispatcher_.fetchLabel(expr->getDecl().getDecl());
565+
dispatcher_.emit(LookupExprsTrap{label, baseLabel, declLabel});
566+
}
567+
568+
/*
569+
* `DirectToStorage`, `DirectToImplementation`, and `DirectToImplementation` must be
570+
* constructable from a `Label` argument, and values of `T` must have a
571+
* `getAccessSemantics` member that returns a `swift::AccessSemantics`.
572+
*/
573+
template <typename DirectToStorage,
574+
typename DirectToImplementation,
575+
typename Ordinary,
576+
typename T,
577+
typename Label>
578+
void emitAccessorSemantics(T* ast, Label label) {
579+
switch (ast->getAccessSemantics()) {
580+
case swift::AccessSemantics::DirectToStorage:
581+
dispatcher_.emit(DirectToStorage{label});
582+
break;
583+
case swift::AccessSemantics::DirectToImplementation:
584+
dispatcher_.emit(DirectToImplementation{label});
585+
break;
586+
case swift::AccessSemantics::Ordinary:
587+
dispatcher_.emit(Ordinary{label});
588+
break;
589+
}
590+
}
545591
};
546592

547593
} // namespace codeql

0 commit comments

Comments
 (0)