@@ -75,7 +75,29 @@ class FindCapturedVars : public ASTWalker {
75
75
76
76
// We want to look through type aliases here.
77
77
type = type->getCanonicalType ();
78
-
78
+
79
+ class TypeCaptureWalker : public TypeWalker {
80
+ AnyFunctionRef AFR;
81
+ llvm::function_ref<void (Type)> Callback;
82
+ public:
83
+ explicit TypeCaptureWalker (AnyFunctionRef AFR,
84
+ llvm::function_ref<void (Type)> callback)
85
+ : AFR(AFR), Callback(callback) {}
86
+
87
+ Action walkToTypePre (Type ty) override {
88
+ Callback (ty);
89
+ // Pseudogeneric classes don't use their generic parameters so we
90
+ // don't need to visit them.
91
+ if (AFR.isObjC ()) {
92
+ if (auto clas = dyn_cast_or_null<ClassDecl>(ty->getAnyNominal ())) {
93
+ if (clas->usesObjCGenericsModel ()) {
94
+ return Action::SkipChildren;
95
+ }
96
+ }
97
+ }
98
+ return Action::Continue;
99
+ }
100
+ };
79
101
// If the type contains dynamic 'Self', conservatively assume we will
80
102
// need 'Self' metadata at runtime. We could generalize the analysis
81
103
// used below for usages of generic parameters in Objective-C
@@ -88,14 +110,14 @@ class FindCapturedVars : public ASTWalker {
88
110
// retainable pointer. Similarly stored property access does not
89
111
// need it, etc.
90
112
if (type->hasDynamicSelfType ()) {
91
- type.visit ( [&](Type t) {
113
+ type.walk ( TypeCaptureWalker (AFR, [&](Type t) {
92
114
if (auto *dynamicSelf = t->getAs <DynamicSelfType>()) {
93
115
if (DynamicSelfCaptureLoc.isInvalid ()) {
94
116
DynamicSelfCaptureLoc = loc;
95
117
DynamicSelf = dynamicSelf;
96
118
}
97
119
}
98
- });
120
+ })) ;
99
121
}
100
122
101
123
// Similar to dynamic 'Self', IRGen doesn't really need type metadata
@@ -106,13 +128,13 @@ class FindCapturedVars : public ASTWalker {
106
128
// instead, but even there we don't really have enough information to
107
129
// perform it accurately.
108
130
if (type->hasArchetype ()) {
109
- type.visit ( [&](Type t) {
131
+ type.walk ( TypeCaptureWalker (AFR, [&](Type t) {
110
132
if (t->is <ArchetypeType>() &&
111
133
!t->isOpenedExistential () &&
112
134
GenericParamCaptureLoc.isInvalid ()) {
113
135
GenericParamCaptureLoc = loc;
114
136
}
115
- });
137
+ })) ;
116
138
}
117
139
}
118
140
@@ -499,6 +521,17 @@ class FindCapturedVars : public ASTWalker {
499
521
|| isa<ExistentialMetatypeToObjectExpr>(E))
500
522
return false ;
501
523
524
+ // Casting to an ObjC class doesn't require the metadata of its type
525
+ // parameters, if any.
526
+ if (auto cast = dyn_cast<CheckedCastExpr>(E)) {
527
+ if (auto clas = dyn_cast_or_null<ClassDecl>(
528
+ cast->getCastTypeLoc ().getType ()->getAnyNominal ())) {
529
+ if (clas->usesObjCGenericsModel ()) {
530
+ return false ;
531
+ }
532
+ }
533
+ }
534
+
502
535
// Assigning an object doesn't require type metadata.
503
536
if (auto assignment = dyn_cast<AssignExpr>(E))
504
537
return !assignment->getSrc ()->getType ()
0 commit comments