18
18
#include " GenKeyPath.h"
19
19
#include " swift/AST/ASTContext.h"
20
20
#include " swift/AST/ASTMangler.h"
21
+ #include " swift/AST/Decl.h"
21
22
#include " swift/AST/DiagnosticsIRGen.h"
22
23
#include " swift/AST/ExtInfo.h"
23
24
#include " swift/AST/GenericEnvironment.h"
26
27
#include " swift/AST/Pattern.h"
27
28
#include " swift/AST/SemanticAttrs.h"
28
29
#include " swift/AST/SubstitutionMap.h"
30
+ #include " swift/AST/Type.h"
31
+ #include " swift/AST/TypeExpansionContext.h"
32
+ #include " swift/AST/TypeVisitor.h"
29
33
#include " swift/AST/Types.h"
30
34
#include " swift/Basic/Assertions.h"
31
35
#include " swift/Basic/ExternalUnion.h"
@@ -2472,6 +2476,53 @@ static void emitDynamicSelfMetadata(IRGenSILFunction &IGF) {
2472
2476
IGF.setDynamicSelfMetadata (selfTy, isExact, value, selfKind);
2473
2477
}
2474
2478
2479
+ // / C++ interop might refer to the type metadata in some scenarios.
2480
+ // / This function covers those cases and makes sure metadata is emitted
2481
+ // / for the foreign types.
2482
+ static void noteUseOfMetadataByCXXInterop (IRGenerator &IRGen,
2483
+ const SILFunction *f,
2484
+ const TypeExpansionContext &context) {
2485
+ auto type = f->getLoweredFunctionType ();
2486
+
2487
+ // Notes the use of foreign types in generic arguments for C++ interop.
2488
+ auto processType = [&](CanType type) {
2489
+ struct Walker : TypeWalker {
2490
+ Walker (IRGenerator &IRGen) : IRGen(IRGen) {}
2491
+
2492
+ Action walkToTypePre (Type ty) override {
2493
+ if (auto *BGT = ty->getAs <BoundGenericType>())
2494
+ genericDepth++;
2495
+ else if (auto *nominal = ty->getAs <NominalType>())
2496
+ noteUseOfTypeMetadata (nominal->getDecl ());
2497
+ return Action::Continue;
2498
+ }
2499
+
2500
+ Action walkToTypePost (Type ty) override {
2501
+ if (auto *BGT = ty->getAs <BoundGenericType>())
2502
+ genericDepth--;
2503
+
2504
+ return Action::Continue;
2505
+ }
2506
+
2507
+ void noteUseOfTypeMetadata (NominalTypeDecl *type) {
2508
+ if (genericDepth == 0 )
2509
+ return ;
2510
+ if (!IRGen.hasLazyMetadata (type) || !type->hasClangNode ())
2511
+ return ;
2512
+ IRGen.noteUseOfTypeMetadata (type);
2513
+ }
2514
+ IRGenerator &IRGen;
2515
+ int genericDepth = 0 ;
2516
+ } walker{IRGen};
2517
+ type.walk (walker);
2518
+ };
2519
+
2520
+ for (const auto ¶m : type->getParameters ())
2521
+ processType (param.getArgumentType (IRGen.SIL , type, context));
2522
+ for (const auto &result : type->getResultsWithError ())
2523
+ processType (result.getReturnValueType (IRGen.SIL , type, context));
2524
+ }
2525
+
2475
2526
// / Emit the definition for the given SIL constant.
2476
2527
void IRGenModule::emitSILFunction (SILFunction *f) {
2477
2528
if (f->isExternalDeclaration ())
@@ -2487,6 +2538,12 @@ void IRGenModule::emitSILFunction(SILFunction *f) {
2487
2538
f->isAvailableExternally ())
2488
2539
return ;
2489
2540
2541
+ // Type metadata for foreign references is not yet supported on Windows. Bug #76168.
2542
+ if (Context.LangOpts .EnableCXXInterop &&
2543
+ f->getLinkage () == SILLinkage::Public &&
2544
+ !Context.LangOpts .Target .isOSWindows ())
2545
+ noteUseOfMetadataByCXXInterop (IRGen, f, TypeExpansionContext (*f));
2546
+
2490
2547
PrettyStackTraceSILFunction stackTrace (" emitting IR" , f);
2491
2548
IRGenSILFunction (*this , f).emitSILFunction ();
2492
2549
}
0 commit comments