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"
@@ -2485,6 +2489,53 @@ static void emitDynamicSelfMetadata(IRGenSILFunction &IGF) {
2485
2489
IGF.setDynamicSelfMetadata (selfTy, isExact, value, selfKind);
2486
2490
}
2487
2491
2492
+ // / C++ interop might refer to the type metadata in some scenarios.
2493
+ // / This function covers those cases and makes sure metadata is emitted
2494
+ // / for the foreign types.
2495
+ static void noteUseOfMetadataByCXXInterop (IRGenerator &IRGen,
2496
+ const SILFunction *f,
2497
+ const TypeExpansionContext &context) {
2498
+ auto type = f->getLoweredFunctionType ();
2499
+
2500
+ // Notes the use of foreign types in generic arguments for C++ interop.
2501
+ auto processType = [&](CanType type) {
2502
+ struct Walker : TypeWalker {
2503
+ Walker (IRGenerator &IRGen) : IRGen(IRGen) {}
2504
+
2505
+ Action walkToTypePre (Type ty) override {
2506
+ if (auto *BGT = ty->getAs <BoundGenericType>())
2507
+ genericDepth++;
2508
+ else if (auto *nominal = ty->getAs <NominalType>())
2509
+ noteUseOfTypeMetadata (nominal->getDecl ());
2510
+ return Action::Continue;
2511
+ }
2512
+
2513
+ Action walkToTypePost (Type ty) override {
2514
+ if (auto *BGT = ty->getAs <BoundGenericType>())
2515
+ genericDepth--;
2516
+
2517
+ return Action::Continue;
2518
+ }
2519
+
2520
+ void noteUseOfTypeMetadata (NominalTypeDecl *type) {
2521
+ if (genericDepth == 0 )
2522
+ return ;
2523
+ if (!IRGen.hasLazyMetadata (type) || !type->hasClangNode ())
2524
+ return ;
2525
+ IRGen.noteUseOfTypeMetadata (type);
2526
+ }
2527
+ IRGenerator &IRGen;
2528
+ int genericDepth = 0 ;
2529
+ } walker{IRGen};
2530
+ type.walk (walker);
2531
+ };
2532
+
2533
+ for (const auto ¶m : type->getParameters ())
2534
+ processType (param.getArgumentType (IRGen.SIL , type, context));
2535
+ for (const auto &result : type->getResultsWithError ())
2536
+ processType (result.getReturnValueType (IRGen.SIL , type, context));
2537
+ }
2538
+
2488
2539
// / Emit the definition for the given SIL constant.
2489
2540
void IRGenModule::emitSILFunction (SILFunction *f) {
2490
2541
if (f->isExternalDeclaration ())
@@ -2496,6 +2547,12 @@ void IRGenModule::emitSILFunction(SILFunction *f) {
2496
2547
f->isAvailableExternally ())
2497
2548
return ;
2498
2549
2550
+ // Type metadata for foreign references is not yet supported on Windows. Bug #76168.
2551
+ if (Context.LangOpts .EnableCXXInterop &&
2552
+ f->getLinkage () == SILLinkage::Public &&
2553
+ !Context.LangOpts .Target .isOSWindows ())
2554
+ noteUseOfMetadataByCXXInterop (IRGen, f, TypeExpansionContext (*f));
2555
+
2499
2556
PrettyStackTraceSILFunction stackTrace (" emitting IR" , f);
2500
2557
IRGenSILFunction (*this , f).emitSILFunction ();
2501
2558
}
0 commit comments