20
20
#include " swift/AST/PrettyStackTrace.h"
21
21
#include " swift/AST/ProtocolConformance.h"
22
22
#include " swift/AST/SubstitutionMap.h"
23
+ #include " swift/Basic/Platform.h"
23
24
#include " swift/IRGen/Linking.h"
24
25
#include " swift/Reflection/MetadataSourceBuilder.h"
25
26
#include " swift/Reflection/Records.h"
38
39
#include " IRGenMangler.h"
39
40
#include " IRGenModule.h"
40
41
#include " LoadableTypeInfo.h"
42
+ #include " MetadataRequest.h"
41
43
42
44
using namespace swift ;
43
45
using namespace irgen ;
@@ -168,13 +170,117 @@ class PrintMetadataSource
168
170
}
169
171
};
170
172
173
+ // Return whether the Swift runtime supports demangling a given
174
+ // type.
175
+ static bool
176
+ doesRuntimeSupportDemanglingType (IRGenModule &IGM, CanType type) {
177
+ // Associated types of opaque types weren't mangled in a usable form by the
178
+ // Swift 5.1 runtime, so we needed to add a new mangling in 5.2.
179
+ if (type->hasOpaqueArchetype ()) {
180
+ auto hasOpaqueAssocType = type.findIf ([](CanType t) -> bool {
181
+ if (auto a = dyn_cast<NestedArchetypeType>(t)) {
182
+ return isa<OpaqueTypeArchetypeType>(a->getRoot ());
183
+ }
184
+ return false ;
185
+ });
186
+
187
+ if (hasOpaqueAssocType)
188
+ return false ;
189
+ // Although opaque types in general were only added in Swift 5.1,
190
+ // declarations that use them are already covered by availability
191
+ // guards, so we don't need to limit availability of mangled names
192
+ // involving them.
193
+ }
194
+
195
+ return true ;
196
+ }
197
+
198
+ // Produce a fallback mangled type name that uses an open-coded callback
199
+ // to form the metadata. This is useful for working around bugs in older
200
+ // runtimes, or supporting new type system features when deploying back.
201
+ //
202
+ // Note that this functionality is limited, because the demangler callback
203
+ // mechanism can only produce complete metadata. It can't be used in situations
204
+ // where completing the metadata during demangling might cause cyclic
205
+ // dependencies.
206
+ static llvm::Constant *
207
+ getTypeRefByFunction (IRGenModule &IGM,
208
+ CanGenericSignature sig,
209
+ CanType t) {
210
+ IRGenMangler mangler;
211
+ std::string symbolName =
212
+ mangler.mangleSymbolNameForMangledMetadataAccessorString (
213
+ " get_type_metadata" , sig, t);
214
+ auto constant = IGM.getAddrOfStringForMetadataRef (symbolName, /* align*/ 2 ,
215
+ /* low bit*/ false ,
216
+ [&](ConstantInitBuilder &B) {
217
+ llvm::Function *accessor;
218
+
219
+ // Otherwise, we need to emit a helper function to bind the arguments
220
+ // out of the demangler's argument buffer.
221
+ auto fnTy = llvm::FunctionType::get (IGM.TypeMetadataPtrTy ,
222
+ {IGM.Int8PtrTy }, /* vararg*/ false );
223
+ accessor =
224
+ llvm::Function::Create (fnTy, llvm::GlobalValue::PrivateLinkage,
225
+ symbolName, IGM.getModule ());
226
+ accessor->setAttributes (IGM.constructInitialAttributes ());
227
+
228
+ SmallVector<GenericRequirement, 4 > requirements;
229
+ GenericEnvironment *genericEnv = nullptr ;
230
+ if (sig) {
231
+ enumerateGenericSignatureRequirements (sig,
232
+ [&](GenericRequirement reqt) { requirements.push_back (reqt); });
233
+ genericEnv = sig->createGenericEnvironment ();
234
+ }
235
+
236
+ {
237
+ IRGenFunction IGF (IGM, accessor);
238
+ if (IGM.DebugInfo )
239
+ IGM.DebugInfo ->emitArtificialFunction (IGF, accessor);
240
+
241
+ auto bindingsBufPtr = IGF.collectParameters ().claimNext ();
242
+
243
+ auto substT = genericEnv
244
+ ? genericEnv->mapTypeIntoContext (t)->getCanonicalType ()
245
+ : t;
246
+
247
+ bindFromGenericRequirementsBuffer (IGF, requirements,
248
+ Address (bindingsBufPtr, IGM.getPointerAlignment ()),
249
+ MetadataState::Complete,
250
+ [&](CanType t) {
251
+ return genericEnv
252
+ ? genericEnv->mapTypeIntoContext (t)->getCanonicalType ()
253
+ : t;
254
+ });
255
+
256
+ auto ret = IGF.emitTypeMetadataRef (substT);
257
+ IGF.Builder .CreateRet (ret);
258
+ }
259
+ // Form the mangled name with its relative reference.
260
+ auto S = B.beginStruct ();
261
+ S.setPacked (true );
262
+ S.add (llvm::ConstantInt::get (IGM.Int8Ty , 255 ));
263
+ S.add (llvm::ConstantInt::get (IGM.Int8Ty , 9 ));
264
+ S.addRelativeAddress (accessor);
265
+
266
+ // And a null terminator!
267
+ S.addInt (IGM.Int8Ty , 0 );
268
+
269
+ return S.finishAndCreateFuture ();
270
+ });
271
+ return constant;
272
+ }
273
+
171
274
llvm::Constant *IRGenModule::getTypeRef (Type type,
172
275
GenericSignature *genericSig,
173
276
MangledTypeRefRole role) {
174
- return getTypeRef (type->getCanonicalType (genericSig), role);
277
+ return getTypeRef (type->getCanonicalType (genericSig),
278
+ genericSig ? genericSig->getCanonicalSignature () : CanGenericSignature (),
279
+ role);
175
280
}
176
281
177
282
llvm::Constant *IRGenModule::getTypeRef (CanType type,
283
+ CanGenericSignature genericSig,
178
284
MangledTypeRefRole role) {
179
285
180
286
switch (role) {
@@ -184,6 +290,12 @@ llvm::Constant *IRGenModule::getTypeRef(CanType type,
184
290
// ensuring that we can always reconstruct type metadata from a mangled name
185
291
// in-process.
186
292
IRGen.noteUseOfTypeMetadata (type);
293
+ // If the minimum deployment target's runtime demangler wouldn't understand
294
+ // this mangled name, then fall back to generating a "mangled name" with a
295
+ // symbolic reference with a callback function.
296
+ if (!doesRuntimeSupportDemanglingType (*this , type)) {
297
+ return getTypeRefByFunction (*this , genericSig, type);
298
+ }
187
299
break ;
188
300
189
301
case MangledTypeRefRole::Reflection:
@@ -223,7 +335,7 @@ IRGenModule::emitWitnessTableRefString(CanType type,
223
335
224
336
IRGenMangler mangler;
225
337
std::string symbolName =
226
- mangler.mangleSymbolNameForKeyPathMetadata (
338
+ mangler.mangleSymbolNameForMangledConformanceAccessorString (
227
339
" get_witness_table" , genericSig, type, conformance);
228
340
229
341
return getAddrOfStringForMetadataRef (symbolName, /* alignment=*/ 2 ,
@@ -376,7 +488,10 @@ class ReflectionMetadataBuilder {
376
488
void addTypeRef (Type type, GenericSignature *genericSig,
377
489
MangledTypeRefRole role =
378
490
MangledTypeRefRole::Reflection) {
379
- addTypeRef (type->getCanonicalType (genericSig), role);
491
+ addTypeRef (type->getCanonicalType (genericSig),
492
+ genericSig ? genericSig->getCanonicalSignature ()
493
+ : CanGenericSignature (),
494
+ role);
380
495
}
381
496
382
497
// / Add a 32-bit relative offset to a mangled typeref string
@@ -388,9 +503,10 @@ class ReflectionMetadataBuilder {
388
503
// / For reflection records which are demangled to produce type metadata
389
504
// / in-process, pass MangledTypeRefRole::Metadata instead.
390
505
void addTypeRef (CanType type,
506
+ CanGenericSignature sig,
391
507
MangledTypeRefRole role =
392
508
MangledTypeRefRole::Reflection) {
393
- B.addRelativeAddress (IGM.getTypeRef (type, role));
509
+ B.addRelativeAddress (IGM.getTypeRef (type, sig, role));
394
510
addBuiltinTypeRefs (type);
395
511
}
396
512
@@ -487,7 +603,10 @@ class AssociatedTypeMetadataBuilder : public ReflectionMetadataBuilder {
487
603
for (auto AssocTy : AssociatedTypes) {
488
604
auto NameGlobal = IGM.getAddrOfFieldName (AssocTy.first );
489
605
B.addRelativeAddress (NameGlobal);
490
- addTypeRef (AssocTy.second );
606
+ addTypeRef (AssocTy.second ,
607
+ Nominal->getGenericSignature ()
608
+ ? Nominal->getGenericSignature ()->getCanonicalSignature ()
609
+ : CanGenericSignature ());
491
610
}
492
611
}
493
612
@@ -683,7 +802,7 @@ class FixedTypeMetadataBuilder : public ReflectionMetadataBuilder {
683
802
}
684
803
685
804
void layout () override {
686
- addTypeRef (type);
805
+ addTypeRef (type, CanGenericSignature () );
687
806
688
807
B.addInt32 (ti->getFixedSize ().getValue ());
689
808
@@ -726,7 +845,7 @@ class BoxDescriptorBuilder : public ReflectionMetadataBuilder {
726
845
B.addInt32 (0 ); // Number of sources
727
846
B.addInt32 (0 ); // Number of generic bindings
728
847
729
- addTypeRef (BoxedType);
848
+ addTypeRef (BoxedType, CanGenericSignature () );
730
849
}
731
850
732
851
llvm::GlobalVariable *emit () {
@@ -919,9 +1038,13 @@ class CaptureDescriptorBuilder : public ReflectionMetadataBuilder {
919
1038
B.addInt32 (MetadataSources.size ());
920
1039
B.addInt32 (Layout.getBindings ().size ());
921
1040
1041
+ auto sig = OrigCalleeType->getGenericSignature ()
1042
+ ? OrigCalleeType->getGenericSignature ()->getCanonicalSignature ()
1043
+ : CanGenericSignature ();
1044
+
922
1045
// Now add typerefs of all of the captures.
923
1046
for (auto CaptureType : CaptureTypes) {
924
- addTypeRef (CaptureType);
1047
+ addTypeRef (CaptureType, sig );
925
1048
addBuiltinTypeRefs (CaptureType);
926
1049
}
927
1050
@@ -931,7 +1054,7 @@ class CaptureDescriptorBuilder : public ReflectionMetadataBuilder {
931
1054
auto GenericParam = GenericAndSource.first ->getCanonicalType ();
932
1055
auto Source = GenericAndSource.second ;
933
1056
934
- addTypeRef (GenericParam);
1057
+ addTypeRef (GenericParam, sig );
935
1058
addMetadataSource (Source);
936
1059
}
937
1060
}
0 commit comments