Skip to content

Commit c3968a2

Browse files
authored
Merge pull request github#10854 from github/redsun82/swift-extract-implicit-conversions
Swift: extract all `ImplicitConversionExpr`
2 parents f1fd470 + 789be9a commit c3968a2

File tree

37 files changed

+100
-213
lines changed

37 files changed

+100
-213
lines changed

swift/extractor/visitors/ExprVisitor.cpp

Lines changed: 0 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -279,12 +279,6 @@ void ExprVisitor::visitArrayExpr(swift::ArrayExpr* expr) {
279279
}
280280
}
281281

282-
void ExprVisitor::visitErasureExpr(swift::ErasureExpr* expr) {
283-
auto label = dispatcher_.assignNewLabel(expr);
284-
dispatcher_.emit(ErasureExprsTrap{label});
285-
emitImplicitConversionExpr(expr, label);
286-
}
287-
288282
codeql::TypeExpr ExprVisitor::translateTypeExpr(const swift::TypeExpr& expr) {
289283
TypeExpr entry{dispatcher_.assignNewLabel(expr)};
290284
if (expr.getTypeRepr() && expr.getInstanceType()) {
@@ -299,12 +293,6 @@ codeql::ParenExpr ExprVisitor::translateParenExpr(const swift::ParenExpr& expr)
299293
return entry;
300294
}
301295

302-
void ExprVisitor::visitLoadExpr(swift::LoadExpr* expr) {
303-
auto label = dispatcher_.assignNewLabel(expr);
304-
dispatcher_.emit(LoadExprsTrap{label});
305-
emitImplicitConversionExpr(expr, label);
306-
}
307-
308296
void ExprVisitor::visitInOutExpr(swift::InOutExpr* expr) {
309297
auto label = dispatcher_.assignNewLabel(expr);
310298
assert(expr->getSubExpr() && "InOutExpr has getSubExpr()");
@@ -359,12 +347,6 @@ void ExprVisitor::visitOptionalTryExpr(swift::OptionalTryExpr* expr) {
359347
emitAnyTryExpr(expr, label);
360348
}
361349

362-
void ExprVisitor::visitInjectIntoOptionalExpr(swift::InjectIntoOptionalExpr* expr) {
363-
auto label = dispatcher_.assignNewLabel(expr);
364-
dispatcher_.emit(InjectIntoOptionalExprsTrap{label});
365-
emitImplicitConversionExpr(expr, label);
366-
}
367-
368350
void ExprVisitor::visitConstructorRefCallExpr(swift::ConstructorRefCallExpr* expr) {
369351
auto label = dispatcher_.assignNewLabel(expr);
370352
dispatcher_.emit(ConstructorRefCallExprsTrap{label});
@@ -442,18 +424,6 @@ void ExprVisitor::visitDictionaryExpr(swift::DictionaryExpr* expr) {
442424
}
443425
}
444426

445-
void ExprVisitor::visitFunctionConversionExpr(swift::FunctionConversionExpr* expr) {
446-
auto label = dispatcher_.assignNewLabel(expr);
447-
dispatcher_.emit(FunctionConversionExprsTrap{label});
448-
emitImplicitConversionExpr(expr, label);
449-
}
450-
451-
void ExprVisitor::visitInOutToPointerExpr(swift::InOutToPointerExpr* expr) {
452-
auto label = dispatcher_.assignNewLabel(expr);
453-
dispatcher_.emit(InOutToPointerExprsTrap{label});
454-
emitImplicitConversionExpr(expr, label);
455-
}
456-
457427
void ExprVisitor::visitMemberRefExpr(swift::MemberRefExpr* expr) {
458428
auto label = dispatcher_.assignNewLabel(expr);
459429
dispatcher_.emit(MemberRefExprsTrap{label});
@@ -465,12 +435,6 @@ void ExprVisitor::visitMemberRefExpr(swift::MemberRefExpr* expr) {
465435
emitLookupExpr(expr, label);
466436
}
467437

468-
void ExprVisitor::visitDerivedToBaseExpr(swift::DerivedToBaseExpr* expr) {
469-
auto label = dispatcher_.assignNewLabel(expr);
470-
dispatcher_.emit(DerivedToBaseExprsTrap{label});
471-
emitImplicitConversionExpr(expr, label);
472-
}
473-
474438
void ExprVisitor::visitKeyPathExpr(swift::KeyPathExpr* expr) {
475439
auto label = dispatcher_.assignNewLabel(expr);
476440
dispatcher_.emit(KeyPathExprsTrap{label});
@@ -506,12 +470,6 @@ void ExprVisitor::visitForceValueExpr(swift::ForceValueExpr* expr) {
506470
dispatcher_.emit(ForceValueExprsTrap{label, subExprLabel});
507471
}
508472

509-
void ExprVisitor::visitPointerToPointerExpr(swift::PointerToPointerExpr* expr) {
510-
auto label = dispatcher_.assignNewLabel(expr);
511-
dispatcher_.emit(PointerToPointerExprsTrap{label});
512-
emitImplicitConversionExpr(expr, label);
513-
}
514-
515473
void ExprVisitor::visitIfExpr(swift::IfExpr* expr) {
516474
auto label = dispatcher_.assignNewLabel(expr);
517475
assert(expr->getCondExpr() && "IfExpr has getCond()");
@@ -583,20 +541,6 @@ codeql::SequenceExpr ExprVisitor::translateSequenceExpr(const swift::SequenceExp
583541
return entry;
584542
}
585543

586-
codeql::BridgeToObjCExpr ExprVisitor::translateBridgeToObjCExpr(
587-
const swift::BridgeToObjCExpr& expr) {
588-
BridgeToObjCExpr entry{dispatcher_.assignNewLabel(expr)};
589-
entry.sub_expr = dispatcher_.fetchLabel(expr.getSubExpr());
590-
return entry;
591-
}
592-
593-
codeql::BridgeFromObjCExpr ExprVisitor::translateBridgeFromObjCExpr(
594-
const swift::BridgeFromObjCExpr& expr) {
595-
BridgeFromObjCExpr entry{dispatcher_.assignNewLabel(expr)};
596-
entry.sub_expr = dispatcher_.fetchLabel(expr.getSubExpr());
597-
return entry;
598-
}
599-
600544
codeql::DotSelfExpr ExprVisitor::translateDotSelfExpr(const swift::DotSelfExpr& expr) {
601545
DotSelfExpr entry{dispatcher_.assignNewLabel(expr)};
602546
fillIdentityExpr(expr, entry);
@@ -624,12 +568,6 @@ TrapLabel<ArgumentTag> ExprVisitor::emitArgument(const swift::Argument& arg) {
624568
return entry.id;
625569
}
626570

627-
void ExprVisitor::emitImplicitConversionExpr(swift::ImplicitConversionExpr* expr,
628-
TrapLabel<ImplicitConversionExprTag> label) {
629-
assert(expr->getSubExpr() && "ImplicitConversionExpr has getSubExpr()");
630-
dispatcher_.emit(ImplicitConversionExprsTrap{label, dispatcher_.fetchLabel(expr->getSubExpr())});
631-
}
632-
633571
void ExprVisitor::emitExplicitCastExpr(swift::ExplicitCastExpr* expr,
634572
TrapLabel<ExplicitCastExprTag> label) {
635573
assert(expr->getSubExpr() && "ExplicitCastExpr has getSubExpr()");

swift/extractor/visitors/ExprVisitor.h

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,23 @@ class ExprVisitor : public AstVisitorBase<ExprVisitor> {
3939
void visitDotSyntaxCallExpr(swift::DotSyntaxCallExpr* expr);
4040
void visitVarargExpansionExpr(swift::VarargExpansionExpr* expr);
4141
void visitArrayExpr(swift::ArrayExpr* expr);
42-
void visitErasureExpr(swift::ErasureExpr* expr);
42+
43+
template <typename E>
44+
TrapClassOf<E> translateImplicitConversionExpr(const E& expr) {
45+
auto entry = dispatcher_.createEntry(expr);
46+
entry.sub_expr = dispatcher_.fetchLabel(expr.getSubExpr());
47+
return entry;
48+
}
49+
4350
codeql::TypeExpr translateTypeExpr(const swift::TypeExpr& expr);
4451
codeql::ParenExpr translateParenExpr(const swift::ParenExpr& expr);
45-
void visitLoadExpr(swift::LoadExpr* expr);
4652
void visitInOutExpr(swift::InOutExpr* expr);
4753
void visitOpaqueValueExpr(swift::OpaqueValueExpr* expr);
4854
void visitTapExpr(swift::TapExpr* expr);
4955
void visitTupleElementExpr(swift::TupleElementExpr* expr);
5056
void visitTryExpr(swift::TryExpr* expr);
5157
void visitForceTryExpr(swift::ForceTryExpr* expr);
5258
void visitOptionalTryExpr(swift::OptionalTryExpr* expr);
53-
void visitInjectIntoOptionalExpr(swift::InjectIntoOptionalExpr* expr);
5459
void visitConstructorRefCallExpr(swift::ConstructorRefCallExpr* expr);
5560
void visitDiscardAssignmentExpr(swift::DiscardAssignmentExpr* expr);
5661
codeql::ClosureExpr translateClosureExpr(const swift::ClosureExpr& expr);
@@ -62,14 +67,10 @@ class ExprVisitor : public AstVisitorBase<ExprVisitor> {
6267
void visitLookupExpr(swift::LookupExpr* expr);
6368
void visitSubscriptExpr(swift::SubscriptExpr* expr);
6469
void visitDictionaryExpr(swift::DictionaryExpr* expr);
65-
void visitFunctionConversionExpr(swift::FunctionConversionExpr* expr);
66-
void visitInOutToPointerExpr(swift::InOutToPointerExpr* expr);
6770
void visitMemberRefExpr(swift::MemberRefExpr* expr);
68-
void visitDerivedToBaseExpr(swift::DerivedToBaseExpr* expr);
6971
void visitKeyPathExpr(swift::KeyPathExpr* expr);
7072
void visitLazyInitializerExpr(swift::LazyInitializerExpr* expr);
7173
void visitForceValueExpr(swift::ForceValueExpr* expr);
72-
void visitPointerToPointerExpr(swift::PointerToPointerExpr* expr);
7374
void visitIfExpr(swift::IfExpr* expr);
7475
void visitKeyPathDotExpr(swift::KeyPathDotExpr* expr);
7576
void visitKeyPathApplicationExpr(swift::KeyPathApplicationExpr* expr);
@@ -80,8 +81,6 @@ class ExprVisitor : public AstVisitorBase<ExprVisitor> {
8081
codeql::UnresolvedMemberExpr translateUnresolvedMemberExpr(
8182
const swift::UnresolvedMemberExpr& expr);
8283
codeql::SequenceExpr translateSequenceExpr(const swift::SequenceExpr& expr);
83-
codeql::BridgeToObjCExpr translateBridgeToObjCExpr(const swift::BridgeToObjCExpr& expr);
84-
codeql::BridgeFromObjCExpr translateBridgeFromObjCExpr(const swift::BridgeFromObjCExpr& expr);
8584
codeql::DotSelfExpr translateDotSelfExpr(const swift::DotSelfExpr& expr);
8685
codeql::ErrorExpr translateErrorExpr(const swift::ErrorExpr& expr);
8786
// The following function requires a non-const parameter because:
@@ -96,8 +95,6 @@ class ExprVisitor : public AstVisitorBase<ExprVisitor> {
9695
void fillAbstractClosureExpr(const swift::AbstractClosureExpr& expr,
9796
codeql::AbstractClosureExpr& entry);
9897
TrapLabel<ArgumentTag> emitArgument(const swift::Argument& arg);
99-
void emitImplicitConversionExpr(swift::ImplicitConversionExpr* expr,
100-
TrapLabel<ImplicitConversionExprTag> label);
10198
void emitExplicitCastExpr(swift::ExplicitCastExpr* expr, TrapLabel<ExplicitCastExprTag> label);
10299
void fillIdentityExpr(const swift::IdentityExpr& expr, codeql::IdentityExpr& entry);
103100
void emitAnyTryExpr(swift::AnyTryExpr* expr, TrapLabel<AnyTryExprTag> label);

swift/extractor/visitors/VisitorBase.h

Lines changed: 63 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,66 +17,101 @@ class VisitorBase {
1717
VisitorBase(SwiftDispatcher& dispatcher) : dispatcher_{dispatcher} {}
1818
};
1919

20+
// define by macro metaprogramming member checkers
21+
// see https://fekir.info/post/detect-member-variables/ for technical details
22+
#define DEFINE_TRANSLATE_CHECKER(KIND, CLASS, PARENT) \
23+
template <typename T, typename = void> \
24+
struct HasTranslate##CLASS##KIND : std::false_type {}; \
25+
\
26+
template <typename T> \
27+
struct HasTranslate##CLASS##KIND<T, decltype((void)std::declval<T>().translate##CLASS##KIND( \
28+
std::declval<swift::CLASS##KIND&>()), \
29+
void())> : std::true_type {};
30+
31+
DEFINE_TRANSLATE_CHECKER(Decl, , )
32+
#define DECL(CLASS, PARENT) DEFINE_TRANSLATE_CHECKER(Decl, CLASS, PARENT)
33+
#define ABSTRACT_DECL(CLASS, PARENT) DEFINE_TRANSLATE_CHECKER(Decl, CLASS, PARENT)
34+
#include "swift/AST/DeclNodes.def"
35+
36+
DEFINE_TRANSLATE_CHECKER(Stmt, , )
37+
#define STMT(CLASS, PARENT) DEFINE_TRANSLATE_CHECKER(Stmt, CLASS, PARENT)
38+
#define ABSTRACT_STMT(CLASS, PARENT) DEFINE_TRANSLATE_CHECKER(Stmt, CLASS, PARENT)
39+
#include "swift/AST/StmtNodes.def"
40+
41+
DEFINE_TRANSLATE_CHECKER(Expr, , )
42+
#define EXPR(CLASS, PARENT) DEFINE_TRANSLATE_CHECKER(Expr, CLASS, PARENT)
43+
#define ABSTRACT_EXPR(CLASS, PARENT) DEFINE_TRANSLATE_CHECKER(Expr, CLASS, PARENT)
44+
#include "swift/AST/ExprNodes.def"
45+
46+
DEFINE_TRANSLATE_CHECKER(Pattern, , )
47+
#define PATTERN(CLASS, PARENT) DEFINE_TRANSLATE_CHECKER(Pattern, CLASS, PARENT)
48+
#include "swift/AST/PatternNodes.def"
49+
50+
DEFINE_TRANSLATE_CHECKER(Type, , )
51+
#define TYPE(CLASS, PARENT) DEFINE_TRANSLATE_CHECKER(Type, CLASS, PARENT)
52+
#define ABSTRACT_TYPE(CLASS, PARENT) DEFINE_TRANSLATE_CHECKER(Type, CLASS, PARENT)
53+
#include "swift/AST/TypeNodes.def"
54+
55+
DEFINE_TRANSLATE_CHECKER(TypeRepr, , )
56+
#define TYPEREPR(CLASS, PARENT) DEFINE_TRANSLATE_CHECKER(TypeRepr, CLASS, PARENT)
57+
#define ABSTRACT_TYPEREPR(CLASS, PARENT) DEFINE_TRANSLATE_CHECKER(TypeRepr, CLASS, PARENT)
58+
#include "swift/AST/TypeReprNodes.def"
2059
} // namespace detail
2160

2261
// we want to override the default swift visitor behaviour of chaining calls to immediate
2362
// superclasses by default and instead provide our own TBD default (using the exact type).
2463
// Moreover, if the implementation class has translate##CLASS##KIND (that uses generated C++
25-
// classes), we want to use that. We detect that by checking its return type. If it is different
26-
// from void (which is what is returned by a private unimplemented member function here) it means
27-
// we have implemented it in the visitor.
28-
#define DEFAULT(KIND, CLASS, PARENT) \
29-
public: \
30-
void visit##CLASS##KIND(swift::CLASS##KIND* e) { \
31-
using TranslateResult = std::invoke_result_t<decltype(&CrtpSubclass::translate##CLASS##KIND), \
32-
CrtpSubclass, swift::CLASS##KIND&>; \
33-
constexpr bool hasTranslateImplementation = !std::is_same_v<TranslateResult, void>; \
34-
if constexpr (hasTranslateImplementation) { \
35-
dispatcher_.emit(static_cast<CrtpSubclass*>(this)->translate##CLASS##KIND(*e)); \
36-
} else { \
37-
dispatcher_.emitUnknown(e); \
38-
} \
39-
} \
40-
\
41-
private: \
42-
void translate##CLASS##KIND(const swift::CLASS##KIND&);
43-
44-
// base class for our AST visitors, getting a SwiftDispatcher member and default emission for
64+
// classes), for the class of for a parent thereof, we want to use that. We detect that by using the
65+
// type traits HasTranslate##CLASS##KIND defined above
66+
#define DEFINE_VISIT(KIND, CLASS, PARENT) \
67+
public: \
68+
void visit##CLASS##KIND(swift::CLASS##KIND* e) { \
69+
if constexpr (detail::HasTranslate##CLASS##KIND<CrtpSubclass>::value) { \
70+
dispatcher_.emit(static_cast<CrtpSubclass*>(this)->translate##CLASS##KIND(*e)); \
71+
} else if constexpr (detail::HasTranslate##PARENT<CrtpSubclass>::value) { \
72+
dispatcher_.emit(static_cast<CrtpSubclass*>(this)->translate##PARENT(*e)); \
73+
} else { \
74+
dispatcher_.emitUnknown(e); \
75+
} \
76+
}
77+
78+
// base class for our AST visitors, getting a SwiftDispatcher member and define_visit emission for
4579
// unknown/TBD entities. Like `swift::ASTVisitor`, this uses CRTP (the Curiously Recurring Template
4680
// Pattern)
4781
template <typename CrtpSubclass>
4882
class AstVisitorBase : public swift::ASTVisitor<CrtpSubclass>, protected detail::VisitorBase {
4983
public:
5084
using VisitorBase::VisitorBase;
5185

52-
#define DECL(CLASS, PARENT) DEFAULT(Decl, CLASS, PARENT)
86+
#define DECL(CLASS, PARENT) DEFINE_VISIT(Decl, CLASS, PARENT)
5387
#include "swift/AST/DeclNodes.def"
5488

55-
#define STMT(CLASS, PARENT) DEFAULT(Stmt, CLASS, PARENT)
89+
#define STMT(CLASS, PARENT) DEFINE_VISIT(Stmt, CLASS, PARENT)
5690
#include "swift/AST/StmtNodes.def"
5791

58-
#define EXPR(CLASS, PARENT) DEFAULT(Expr, CLASS, PARENT)
92+
#define EXPR(CLASS, PARENT) DEFINE_VISIT(Expr, CLASS, PARENT)
5993
#include "swift/AST/ExprNodes.def"
6094

61-
#define PATTERN(CLASS, PARENT) DEFAULT(Pattern, CLASS, PARENT)
95+
#define PATTERN(CLASS, PARENT) DEFINE_VISIT(Pattern, CLASS, PARENT)
6296
#include "swift/AST/PatternNodes.def"
6397

64-
#define TYPEREPR(CLASS, PARENT) DEFAULT(TypeRepr, CLASS, PARENT)
98+
#define TYPEREPR(CLASS, PARENT) DEFINE_VISIT(TypeRepr, CLASS, PARENT)
6599
#include "swift/AST/TypeReprNodes.def"
66100
};
67101

68-
// base class for our type visitor, getting a SwiftDispatcher member and default emission for
102+
// base class for our type visitor, getting a SwiftDispatcher member and define_visit emission for
69103
// unknown/TBD types. Like `swift::TypeVisitor`, this uses CRTP (the Curiously Recurring Template
70104
// Pattern)
71105
template <typename CrtpSubclass>
72106
class TypeVisitorBase : public swift::TypeVisitor<CrtpSubclass>, protected detail::VisitorBase {
73107
public:
74108
using VisitorBase::VisitorBase;
75109

76-
#define TYPE(CLASS, PARENT) DEFAULT(Type, CLASS, PARENT)
110+
#define TYPE(CLASS, PARENT) DEFINE_VISIT(Type, CLASS, PARENT)
77111
#include "swift/AST/TypeNodes.def"
78112
};
79113

80-
#undef DEFAULT
114+
#undef DEFINE_TRANSLATE_CHECKER
115+
#undef DEFINE_VISIT
81116

82117
} // namespace codeql

swift/ql/test/extractor-tests/generated/expr/AnyHashableErasureExpr/MISSING_SOURCE.txt

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

swift/ql/test/extractor-tests/generated/expr/ArchetypeToSuperExpr/MISSING_SOURCE.txt

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

swift/ql/test/extractor-tests/generated/expr/ArrayToPointerExpr/MISSING_SOURCE.txt

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

swift/ql/test/extractor-tests/generated/expr/ClassMetatypeToObjectExpr/MISSING_SOURCE.txt

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

swift/ql/test/extractor-tests/generated/expr/CollectionUpcastConversionExpr/MISSING_SOURCE.txt

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

swift/ql/test/extractor-tests/generated/expr/CovariantFunctionConversionExpr/MISSING_SOURCE.txt

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

swift/ql/test/extractor-tests/generated/expr/CovariantReturnConversionExpr/MISSING_SOURCE.txt

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

0 commit comments

Comments
 (0)